在数组中推送新项目时查看不更新 - AngularJS

时间:2016-06-29 17:47:28

标签: javascript angularjs promise angularjs-ng-repeat

我有一个问题,遗憾的是,即使查看相关的StackOverflow Q / A,我也无法在一段时间内解决。

  

我正在使用 MEAN 构建应用程序,我遇到了问题   当我需要通过ng-repeat呈现新项目时。

     

我有很多项存储在MongoDB实例中,我很完美   能够通过API调用获取所有这些。

     

我一开始只需要显示24个项目,每个项目需要再显示24个项目   用户点击显示更多按钮的时间。我总是需要   在旧的之后将它们连接起来。

     

它与前24个项目完美配合,但它不会渲染   其他项目。

     

当我尝试记录新获取的项目时,我没有遇到任何问题。   我能够看到他们的属性等等。

这是我的项目的简短查看

<div class="myItem" ng-repeat="item in searchCtrl.items track by $index">
  . . . .
</div>

这是我的显示更多按钮

<a class="showMoreButton" ng-click="searchCtrl.goToNextPage()">show more</a>

这是我的控制器的简化版本,也称为 searchCtrl

function SearchController($scope, ItemFactory) {

  var vm = this;

  //Needed for pagination, 24 items at a time, starting from page 1
  vm.searchParams = {
    size   : 24,
    page   : 1
  }      

  //Initialize Empty Array to Contain Items
  vm.items = [];

  /*Calling fetchItems to fetch the items the very 
    first time the Controller is called*/
  fetchItems();

  //Calls goToPage passing it a new page (It handles pagination)
  vm.goToNextPage = function() {
    var next = parseInt(vm.info.currentPage) + 1;
    vm.goToPage(next);
  };

  //Calls fetchItems after setting the new page
  vm.goToPage = function(page) {
    vm.searchParams.page = page;
    fetchItems();
  };      

  //Calls getItems and pushes the single items into vm.items
  function fetchItems(){
    ItemFactory.getItems(vm.searchParams).then(function(response){

        //iterates trough items
        for (var i = 0; i < response.data.data.length; i++) {
          //Log current item
          console.log(JSON.stringify(response.data.data[i]));
          //push current item into vm.items
          vm.items.push(response.data.data[i]);
        }

        //Print correctly the new items pool
        console.log(vm.items);

    }, function(error){
        $log.error(error);
    });
  }      

};

这是 ItemFactory 的简化版:

angular.module('myApp').factory('ItemFactory', 
                function ($http, API_URL) {

  //Getting items from API
  function getItems(params) {

    return $http.get(API_URL + '/item',{params: params}
    ).then(function success(response) {

        return response;
    });
  }

  return {
    getItems : getItems
  }

});

控制器绑定到我的视图,它可以正常工作。我正在使用这种模块化的方法,它总是很完美:

'use strict';
angular.module('myApp')
.config(itemRoute);

function itemRoute($stateProvider) {
    $stateProvider
        .state('index.items', {
            url             : 'index/items',
            parent          : 'index',
            templateUrl     : 'app/main-pages/items/items.html',
            controller      : 'SearchController',
            controllerAs    : 'searchCtrl'
    });
}

我也尝试使用concat代替使用for循环项目,但结果不会改变:

//Instead of looping
vm.items = vm.items.concat(response.data.data);

实质上

  • 我只能渲染前24个项目
  • 即使将所有其他项目正确插入到项目数组
  • 中,也无法呈现所有其他项目
  • 从25开始的项目等等不会进入DOM
  • 我已尝试使用$scope.$apply();,但我得到digest errors

问题

  1. 造成这种情况的原因是什么?
  2. 我该如何解决这个问题?
  3. 提前致谢,如果您需要任何澄清,请在下面发表评论。

1 个答案:

答案 0 :(得分:0)

我设法解决了这个问题,在ItemFactory中获取新项目并将监听器附加到该消息时,从SearchController广播消息。当广播ItemDataRefresh时,SearchController会连接新数据。

<强> ItemFactory

function getItems(params) {

    return $http.get(API_URL + '/item',{params: params}
    ).then(function success(response) {
        $rootScope.$broadcast('refreshData', response.data);
        return response;
    });
}

<强> SearchController

function fetchItems(){
    ItemFactory.getItems(vm.searchParams).then(function(response){

      //When vm.items is empty
      if (!vm.items.length) {
        vm.items = vm.items.concat(response.data.data);
      }

      //on refreshData
      $scope.$on('refreshData', function(event, data){
        vm.items = vm.items.concat(data.data);
      });

    }, function(error){
        $log.error(error);
    });
}

我知道我不应该使用rootScope所以我仍然在寻找一种方法让它以更清洁的方式运作。

我希望它会帮助别人。