当向数组中推送新项时,视图不更新

View not updating when pushing new items in an Array - AngularJS

本文关键字:视图 更新 新项时 数组      更新时间:2023-09-26

我有一个问题,不幸的是,我不能在一段时间内解决,甚至看着相关的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
  }
});

Controller绑定到我的视图,它应该工作。我使用这种模块化的方法,它总是工作得很好:

'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. 我该如何解决这个问题?

提前感谢,如果你需要任何澄清,请在下面发表评论。

我设法解决了这个问题广播消息从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,所以我仍然在寻找一种方法使它以更干净的方式工作。

我希望它能帮助到别人。