0

我正在使用 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>

任何帮助表示赞赏。

4

3 回答 3

2

您可以确保在控制器中分配产品之前完成承诺,并避免多次运行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;
    });
}]);

那应该可以解决您的问题。

于 2018-07-15T00:49:24.260 回答
0

如果我正确理解您的问题,那么您几乎没有解决方法。一种是$apply()在你的ajax调用中使用,它会做什么?有时当一个 promise 被 return 时,值不会被 angular 更新。它会返回一个空的 obj。通过调用$apply(),您可以更新范围。第二种解决方法是首先调用服务并发送您的请求,然后创建一个返回函数,该函数将返回您刚刚在上述服务中调用的 obj。Setter 和 Getter 的概念,我使用这种方法,我使用一个函数获取数据,另一个函数检索数据。您可以尝试的最后一件事是等到数据提取到您的 obj 中,然后返回它。如果每次都调用该服务,则当您使用 ng-repeat 时,ng-repeat行不通,首先在单个 obj 中获取所有数据,然后调用该 obj ,请记住,您只会在控制器中调用一次 service 。该服务将在 ng-repeat 之前返回您的数据。

于 2018-07-14T05:24:13.607 回答
-2

尝试确保服务已启动并正在运行/返回后端数据..然后检查此示例:

https://plnkr.co/edit/l7lGPRIs0ZuDWpVK2pX8?p=preview

角 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);
于 2018-07-14T00:04:01.697 回答