0

目前,我的 Angular 应用程序如下所示:

工厂在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";
}

store.js(下)是我的问题所在 - 目前this.products[]需要内联分配。我需要这个来加载一个外部 JSON 文件(也在下面)。我尝试了几件事,从包含/传递promisetovar myStore = new store();到实际包含与inside of$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"
   },
   ...
]

对于那些感兴趣的人,我的项目基于此:使用 AngularJS 构建的购物车应用程序

提前谢谢了。


更新

我能够完成我想要的,但我不确定这是最好的(阅读:正确)方法。简而言之,我添加了一个名为“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部分的

<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>
4

1 回答 1

1

正如我在评论中概述的那样, InventoryService 在您的情况下不是必需的, $q 和 $http.get 就足够了。

引用自评论:

您可以尝试让 products 和 hero 都承诺,稍后当 HTTP 响应时,一次解决两个延迟对象。

代码:

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

于 2013-07-10T21:21:51.180 回答