【问题标题】:Angular 'track by' not working with $resource arrayAngular 'track by' 不适用于 $resource 数组
【发布时间】:2015-06-26 16:09:29
【问题描述】:

在我工厂的方法中,我从服务器返回一个带有 Angular 的 $resource 的数组:

var resource = $resource("vm", {
    session: function() {
        return Auth.token();
    },
    all: '@all',
    vmId: '@vmId'
}, {
    listVM: {
        method: 'GET',
        url: _baseUrl + 'vm/machines',
        isArray: true,
        cache: false
    }
}

...

_obj.getRunningVMs = function(all) {
    return resource.listVM({all: all}).$promise;
};

...

return _obj;

在我的 HTML 中(在模板中服务别名为 vms):

<div ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>

这导致了一个无限的摘要错误:

错误:[$rootScope:infdig] 达到 10 个 $digest() 迭代。中止!
在最后 5 次迭代中触发的观察者:
[["fn: $watchCollectionWatch; newVal: 22; oldVal: 19"],
["fn: $watchCollectionWatch; newVal: 25; oldVal: 22"],
["fn: $watchCollectionWatch; newVal: 28; oldVal: 25"],
["fn: $watchCollectionWatch; newVal: 31; oldVal: 28"],
["fn: $watchCollectionWatch; newVal: 34; oldVal: 31"]]

我知道这是因为方法调用每次都返回一个全新的数组,这导致 Angular 对监视集合的相等性检查失败。

我试过track by

<div ng-show="managing === 'machines'" ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>

导致以下错误:

错误:[ngRepeat:dupes] 不允许在转发器中重复。使用“track by”表达式指定唯一键。中继器:vms.getRunningVMs(true) 中的机器按 machine.id 跟踪,重复键:未定义,重复值:未定义

我知道id 已定义,并且在$index 跟踪时遇到同样的错误。

track by 是否不适合处理返回新数组的函数,即使是track by?我知道它最初是为了避免不必要的 DOM 突变,但它似乎很容易在这种情况下工作。

【问题讨论】:

    标签: javascript angularjs angularjs-ng-repeat


    【解决方案1】:

    来自http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm#comments_43733

    我刚刚意识到的另一件非常重要的事情:

    当使用 Angular 资源 (resource.query(...)) 时,返回值实际上是“未来”而不是数据本身,因此如果 ng-repeat 绑定到 $scope 中的属性实际上是一个未来,当用一个新的未来(例如通过重新加载数据)替换那个未来时,即使使用“跟踪”机制,所有项目都将被销毁并重新创建。我的猜测是,这是因为 future 对象最初基本上是空的,所以在实际填充之前,机制的跟踪无法找到任何项目。

    作为一种解决方法,我使用 resource.query 方法的成功回调并将实际结果设置回 $scope 中的属性。

    类似:

    myResource.query({}, function (data) {
        $scope.divisionItems = data;
    });
    

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 2015-03-02
      • 2018-01-06
      • 1970-01-01
      • 2018-02-22
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2016-02-19
      相关资源
      最近更新 更多