AngularJS-Ng-Repeat不会更新

时间:2018-07-13 23:51:54

标签: angularjs angularjs-ng-repeat angularjs-service

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

感谢您的帮助。

3 个答案:

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