我正在使用Angular在网络商店上工作,并且正在尝试使用服务来清理代码。我希望该服务从REST API加载项目列表,并在各种控制器上对这些项目执行功能。当我尝试使用REST调用返回的数据填充ng-repeat语句时,会发生我的问题-列表永远不会填充所获取的项目。以前,我使用$ scope和$ apply来确保在返回数据时更新了我的DOM-服务中是否可以执行类似的操作?
服务
'use strict';
var serv = angular.module('serv', []);
serv.factory('shopService', function() {
//create the shop client as service varible
var client = window.ShopifyBuy.buildClient({
domain: 'xxxxxxx.myshopify.com',
storefrontAccessToken: 'xxxxxxxxxxxxxxxxx'
});
var products = [];
client.product.fetchAll().then((products_complete) => {
//do things and get the products ready
products.push(item);
});
return {
products: products
}
});
控制器
'use strict';
var serviceApp = angular.module('serviceApp', ['serv']);
serviceApp.controller('CartController', ['shopService', function CartController(shopService) {
//create a reference to the service variable
this.products = shopService.products;
}]);
和HTML
<body>
<div ng-app="serviceApp" ng-controller="CartController as cart">
<ul>
<li ng-repeat="product in cart.products">
<div> {{ product.title }} </div>
</li>
</ul>
</div>
</body>
感谢您的帮助。
答案 0 :(得分:1)
您可以确保在控制器中分配产品之前完成了诺言,并且避免多次运行fetchAll
。您可以更改服务:
serv.factory('shopService', function($q) {
//create the shop client as service varible
var client = window.ShopifyBuy.buildClient({
domain: 'xxxxxxx.myshopify.com',
storefrontAccessToken: 'xxxxxxxxxxxxxxxxx'
});
var products = [];
var fetchAllCompleted = false;
function getProducts() {
var deferred = $q.defer();
if (fetchAllCompleted) {
deferred.resolve(products);
} else {
client.product.fetchAll().then((products_complete) => {
//do things and get the products ready
products.push(item);
fetchAllCompleted = true;
deferred.resolve(products);
});
}
return deferred.promise;
}
return {
getProducts: getProducts
}
});
然后在控制器中
serviceApp.controller('CartController', ['shopService', function CartController(shopService) {
//create a reference to the service variable
shopService.getProducts().then(function(products) {
this.products = products;
});
}]);
那应该可以解决您的问题。
答案 1 :(得分:0)
如果我正确理解您的问题,那么您的解决方法很少。一种是在您的ajax调用中使用$apply()
,它将做什么?有时,在返回诺言时,值不会按角度更新。它将返回一个空的obj。通过调用$apply()
,您可以更新范围。第二种解决方法是先调用service并发送您的请求,然后创建一个return函数,该函数将返回您刚刚在上述service中调用的obj。 Setter和Getter的概念,我使用这种方法,我使用一个函数来获取数据,而另一个函数来获取数据。
您可以尝试的最后一件事是等待数据提取到obj中,然后将其返回。如果每次都调用该服务时使用ng-repeat,则ng-repeat
将不起作用,请首先在单个obj中获取所有数据,然后再调用该obj,请记住,您只会调用service一个控制器中的时间。并且该服务会在ng-repeat之前返回您的数据。
答案 2 :(得分:-1)
尝试确保服务已启动并且正在运行/正在返回后端数据。 然后检查此示例:
https://plnkr.co/edit/l7lGPRIs0ZuDWpVK2pX8?p=preview
Angular JS
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="animations.css" rel="stylesheet" type="text/css">
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script src="//code.angularjs.org/snapshot/angular-animate.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="ngRepeat">
<div ng-controller="repeatController">
I have {{friends.length}} friends. They are:
<input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
<ul class="example-animate-container">
<li class="animate-repeat"
ng-repeat="friend in friends">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
<li class="animate-repeat" ng-if="results.length === 0">
<strong>No results found...</strong>
</li>
</ul>
</div>
</body>
</html>
JS对象:
(function(angular) {
'use strict';
angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
$scope.friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
];
});
})(window.angular);