AngularJS - Ng-Repeat 不更新

AngularJS - Ng-Repeat does not update

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

感谢任何帮助。

尝试确保服务已启动并且running/returning后端数据.. 然后检查这个例子:

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);

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

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

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