【问题标题】:NgRepeat is not updating from an updated arrayNgRepeat 没有从更新的数组中更新
【发布时间】:2017-06-29 01:46:33
【问题描述】:

我有一个应用程序,它获取数据集合(即 400 个对象)并将其存储在一个数组中。在我看来,我正在创建一种无限滚动,基本上当页面加载时,它会插入 5 条记录。然后我在底部有一个标记为 more 的按钮,该按钮转到数据数组并将其分割为 ngRepeat 指令中正在使用的数组。

起初它开始工作,但一直失败。该函数正在被触发,但带有 ngRepeat 的列表没有更新。

我的控制器示例是:

 function ActivityController($uibModal,$http,$q, UserService) {
        var vm = this;
        vm.activity = [];
        vm.activityData = [];
        vm.maxItems = 5;
        vm.getMoreData = getMoreData;
        function getMoreData(){
            vm.activityData = vm.activity.slice(0, vm.activityData.length + 5);
        }

        UserService.getUserActivity()
                .then(function (response) {
                    vm.activity = response.data;
                    vm.activityData = vm.activity.slice(0, 5);
                });
    }

查看:

 <ul class="list-group">
                <li ng-repeat="activity in activityCtrl.activityData | orderBy: 'date':false " class="list-group-item">
                    <p class="nm">
                        <i class="" aria-hidden="true"></i>
                        <strong>@{{ activity.user }}</strong> @{{ activity.operation }} @{{ activity.type }}  @{{ activity.name }} no Gestor</p>
                    <small class="text-muted">@{{ activity.diff}}</small>
                </li>
            </ul>
                <button ng-click="activityCtrl.getMoreData()">more</button>

【问题讨论】:

  • 如果你在getMoreData() 的末尾加上console.log(vm.activityData) 会发生什么。 scope 是否得到更新但更改未反映在视图中?
  • 也许如果你举个例子(比如this plunker)它会帮助说明问题
  • 您能分享您处理的数据吗?我创建了一个fiddle,但我无法重现该问题。 orderBy 过滤器可能有问题。
  • 为什么将 false 传递给 orderBy,这是默认设置?

标签: javascript angularjs arrays angularjs-scope angularjs-ng-repeat


【解决方案1】:

而不是消灭整个阵列。您应该将下一个元素推入其中。

function ActivityController($uibModal,$http,$q, UserService) {
    var vm = this;

    angular.extend(vm, {
        activity: [],
        activityData: [],
        maxItems: 5,
        getMoreData: function () {
            var sizeToGo = vm.activityData.length + maxItems;
            for (var i = vm.activityData.length; i < sizeToGo && i < vm.activity.length; ++i) {
                vm.activityData.push(vm.activity[i]);
            }
        },
        onInit: function () {
            UserService.getUserActivity()
            .then(function (response) {
                vm.activity = response.data;
                vm.activityData = vm.activity.slice(0, 5);
            });
        }
    });

    vm.onInit();
}

您还应该在ng-repeat 中添加track by $index

<li ng-repeat="activity in activityCtrl.activityData track by $index | orderBy: 'date':false " class="list-group-item">
</li>

【讨论】:

  • 当我第一次点击getMoreData函数时插入所有数据,不是每次填充5条记录。
  • 抱歉,我的 for 循环条件出错了。您可以获取新的getMoreData() 功能。
  • 感谢您的反馈,但不幸的是,它遇到了与我相同的问题,在某个时刻开始失败:S
  • 您是否尝试在您的 ng-repeat 中添加 track by $index
【解决方案2】:

我认为您遇到的问题是由于重新分配 vm.activityData 而不是更新其内容引起的。

function ActivityController($uibModal,$http,$q, UserService, $scope) {
    var vm = this;
    vm.activity = [];
    vm.activityData = [];
    vm.maxItems = 5;
    vm.getMoreData = getMoreData;

    function getMoreData(){
        // add another 5 items
        $scope.$apply(function() {
            Array.prototype.push.apply(vm.activityData, vm.activity.slice(vm.activityData.length, 5));
        });
    }

    UserService.getUserActivity()
            .then(function (response) {
                vm.activity = response.data;
                // add the first 5 items
                Array.prototype.push.apply(vm.activityData, vm.activity.slice(0, 5));
            });
}

更新

$scope.$apply()包装vm.activityData的更新

【讨论】:

  • 它没有在 ngRepeat 中更新,它已经保留了最初的 5 条记录
【解决方案3】:

尝试使用$scope.$evalAsync 函数。

    function getMoreData(){
        $scope.$evalAsync(function(){
         vm.activityData = vm.activity.slice(0, vm.activityData.length + 5);
        })  
    }

演示

var app = angular.module("app",[]);

app.controller('MainCtrl', function($scope) {

  $scope.data =[{"name":"a","age":"25"},{"name":"b","age":"23"},{"name":"c","age":"21"},{"name":"d","age":"21"},{"name":"e","age":"22"}];
  
  $scope.data2 =[];
  $scope.updateData = function(){
    var d = {"name":"newA","age":"25"};
     $scope.$evalAsync(function(){
         $scope.data.push(d);
       })
    }
  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
  <input type="button" value="updateData" ng-click="updateData()" />
   <table>
     <tr ng-repeat="d in data">
         <td>{{d.name}}</td>
         <td>{{d.age}}</td>
    </tr>
  </table>
</div>

【讨论】:

    猜你喜欢
    • 2013-03-12
    • 2014-11-21
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    相关资源
    最近更新 更多