简体   繁体   English

Angular:将JSON $ http承诺传递给工厂

[英]Angular : Pass JSON $http promise to factory

At the moment, my Angular app looks like this: 目前,我的Angular应用程序如下所示:

Factory in app.js app.js工厂

StoreApp.factory("DataService", function () {

    // create store
    var myStore = new store();

    // create shopping cart
    var myCart = new shoppingCart("Store");

   // return data object with store and cart
   return {
       store: myStore,
       cart: myCart
   };
});

controller.js

    function storeController($scope, $http, $routeParams, $location, DataService) {

            $scope.store = DataService.store;
            $scope.cart = DataService.cart;

            // use routing to pick the selected product
            if ($routeParams.productUrlTitle != null) {
                $scope.product = $scope.store.getProduct($routeParams.productUrlTitle) || $scope.store.getHero($routeParams.productUrlTitle);
            }

            $scope.predicate = '-price';
            $scope.store.isCart = $location.path() == "/cart";
}

In store.js (below) is where my issue is — currently this.products[] takes inline assignments. store.js (下图)是我的问题所在-当前this.products[]需要进行内联分配。 I need this to instead load an external JSON file (also below). 我需要它来代替加载外部JSON文件(也在下面)。 I've tried several things from including/passing the promise to var myStore = new store(); 我已经尝试了包括/通过对var myStore = new store();promise几件事var myStore = new store(); , to actually including $http.get() paired with .then() inside of store.js — to no avail. ,实际上包括$http.get()与之配对.then()store.js -无济于事。

store.js

function store() {
   this.products = [
       new product("USD", 20, "https://foo.jpg", "Name", "Description"),
   new product("USD", 20, "https://bar.jpg", "Name", "Description"),
];

}
store.prototype.getProduct = function (urlTitle) {
    for (var i = 0; i < this.products.length; i++) {
    if (this.products[i].urlTitle == urlTitle)
        return this.products[i];
    }
    return null;
}

payload.json

[
    {
    "currency": "usd",
    "cost": 1000,
    "image_url": "https://whatever.domain/someimage.jpg",
    "id": "xyz",
    "name": "A title",
    "description": "Some details"
   },
   ...
]

For those interested, my project is based on this: A Shopping Cart Application Built with AngularJS . 对于那些感兴趣的人,我的项目基于此: 使用AngularJS构建的Shopping Cart应用程序

Many thanks in advance. 提前谢谢了。


Update 更新

I was able to accomplish what I wanted, but I'm not certain it's the best (Read: correct) way to. 我能够完成我想要的,但是我不确定这是最好的方法(阅读:正确)。 In short, I added a new factory called "InventoryService" that I pass to my controller. 简而言之,我添加了一个名为“ InventoryService”的新工厂,并将其传递给控制器​​。

app.js

// New Factory Added

StoreApp.factory('InventoryService', ['$http', '$rootScope',
    function ($http, $rootScope) {
        var inventory = [];

        return {
            getInventory: function () {
                return $http.get('http://localhost/ShoppingCart/payload.json').then(function (response) {
                    inventory = response;
                    $rootScope.$broadcast('handleInventoryService', inventory);
                    return inventory;
                })
            }
        };
    }
]);

controller.js

function storeController($scope, $http, $routeParams, $location, InventoryService, DataService) {

    $scope.name = 'inventory';
    (function () {
        InventoryService.getInventory().then(function (inventory) {
            $scope.inventory = inventory;

            for (var i = 0; i < $scope.inventory.data.length; i++) {
                if ($scope.inventory.data[i].id == '11ca3ea26f0e431eb996a401f292581f2') {
                    DataService.store.hero.push(
                        new product(
                            $scope.inventory.data[i].id,
                            $scope.inventory.data[i].image_url,
                            $scope.inventory.data[i].name,
                            $scope.inventory.data[i].description,
                            $scope.inventory.data[i].cost
                        )
                    );
                } else {
                    DataService.store.products.push(
                        new product(
                            $scope.inventory.data[i].id,
                            $scope.inventory.data[i].image_url,
                            $scope.inventory.data[i].name,
                            $scope.inventory.data[i].description,
                            $scope.inventory.data[i].cost
                        )
                    );
                }
            }

            // get store and cart from service
            $scope.store = DataService.store;
            $scope.cart = DataService.cart;
 ...

store.html partial store.html部分

<div ng-include src="'partials/header.html'"></div>

<div ng-repeat="product in store.hero" class="row-fluid">
    <div class="span12">
        <div class="span4">
            <a href="#/products/{{product.urlTitle}}">
                <img class="img-polaroid" ng-src="{{product.image_url}}" title="{{product.name}}" />
            </a>
        </div>
        <div class="span8">
            <h1 class="tango-tang weight-100">
                {{product.name}}
            </h1>
            <hr />
            <div class="row-fluid">
                <div class="span7">
                    <p>
                        {{product.description}} 
                    </p>
                </div>
                <div class="span5">
                    <div class="well">
                        <h1 class="weight-300 text-center">
                            {{product.price | currency}}
                        </h1>
                    </div>
                    <button class="btn btn-success btn-medium btn-block" ng-click="cart.addItem(product.sku, product.image_url, product.name, product.price, 1)">
                            <i class="icon-plus"></i> Add to Cart 
                    </button> 
                    <a href="#/products/{{product.urlTitle}}" class="btn btn-block">
                        <i class="icon-list"></i> Details
                    </a> 
                </div>
            </div>
        </div>
    </div>
</div>

As I outlined in the comment, the InventoryService isn't necessary in your case, $q and $http.get are enough. 正如我在评论中概述的那样,在您的情况下InventoryService是不必要的,$ q和$ http.get就足够了。

Quoted from comments: 引用评论:

You may try to make products and hero both promises, later when HTTP responded, resolve two deferred objects at once. 您可能会尝试使产品和Hero都承诺,稍后HTTP响应时,立即解析两个延迟的对象。

Code: 码:

App.factory('DataService', function($http, $q) {
    function Store() {
        var heroDeferred = $q.defer();
        var productsDeferred = $q.defer();

        this.hero = heroDeferred.promise;
        this.products = productsDeferred.promise;

        $http.get('/path/to/payload.json').success(function(data) {
            var hero = [];
            var products = [];

            for (var i = 0, len = data.length; i < len; i++) {
                var prod = data[i];
                if (prod.id === 'xyz') {
                    hero.push(prod);
                } else {
                    products.push(prod);
                }
            }

            heroDeferred.resolve(hero);
            productsDeferred.resolve(products);
        });
    }

    Store.prototype.getProduct = function(urlTitle) {
        return this.products.then(function(products) {
            for (var i = 0; i < products.length; i++) { // MUST use products, it's the real value; this.products is a promise
                if (products[i].urlTitle == urlTitle)
                    return products[i];
            }
            return null;
        });
    };

    ...
    return {
        store: new Store()
        ...
    };
});

http://plnkr.co/edit/qff7HYyJnSdEUngeOWVb http://plnkr.co/edit/qff7HYyJnSdEUngeOWVb

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM