[英]Angular : Pass JSON $http promise to factory
At the moment, my Angular app looks like this: 目前,我的Angular应用程序如下所示:
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. 提前谢谢了。
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.