0

我正在处理用户-角色关系,我的代码可以正常工作,只是它在 Angular 端产生了一个无限的摘要错误,我认为这对性能有一些影响。在我的用户类(ES2015)中,我有:

get roles() {
  return Roles.findByIds(this._roleIds).fetch()
}

问题是上面的getter每次都返回一个新对象,所以在Angular看来,它们是不相等的。我试过track by了,如下:

<ul>
  <li ng-repeat="role in user.roles track by role._id">
    {{role.name}}
  </li>
</ul>

引发以下异常:

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [[{"msg":"fn: regularInterceptedExpression","newVal":20,"oldVal":19}],[{"msg":"fn: regularInterceptedExpression","newVal":21,"oldVal":20}],[{"msg":"fn: regularInterceptedExpression","newVal":22,"oldVal":21}],[{"msg":"fn: regularInterceptedExpression","newVal":23,"oldVal":22}],[{"msg":"fn: regularInterceptedExpression","newVal":24,"oldVal":23}]]

没有track by,我看到更长的堆栈跟踪,提到“管理员”

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [[{"msg":"fn: regularInterceptedExpression","newVal":9,"oldVal":8},{"msg":"fn: regularInterceptedExpression","newVal":"Administrator"}],[{"msg":"fn: regularInterceptedExpression","newVal":10,"oldVal":9},{"msg":"fn: regularInterceptedExpression","newVal":"Administrator"}],[{"msg":"fn: regularInterceptedExpression","newVal":11,"oldVal":10},{"msg":"fn: regularInterceptedExpression","newVal":"Administrator"}],[{"msg":"fn: regularInterceptedExpression","newVal":12,"oldVal":11},{"msg":"fn: regularInterceptedExpression","newVal":"Administrator"}],[{"msg":"fn: regularInterceptedExpression","newVal":13,"oldVal":12},{"msg":"fn: regularInterceptedExpression","newVal":"Administrator"}]]

所以现在,我的选择是避免使用 getter,并使用如下updateRoles方法:

updateRoles() {
  this.roles = Roles.findByIds(this._roleIds).fetch()
}

这消除了异常,但似乎updateRoles每次_roleIds数组更改时我都必须手动调用。我只是想知道与我上面提到的方法相比是否有更好的方法。

4

1 回答 1

0

解决这个问题的方法是使 getter 具有幂等性。当给定相同的角色时,它应该返回相同的角色数组_roleIds

这是我解决这个问题的方法。我使用了类似于此 Github 评论的想法: https ://github.com/angular/angular.js/issues/705#issuecomment-36737595

这个想法是使用Object.definePropertyor (ES2015)定义 getter Reflect.defineProperty,这样 getter 将是幂等的。

Reflect.defineProperty(this, "roles", {
  get: Model._makeIdempotent(this, "_roleIds", () => {
    return Roles.find({_id: {$in: this._roleIds}}).fetch()
  }),
})

虽然我没有在自己的代码中手动使用上述方法,并且Reflect.define...在每个“外键”的循环中都被调用,但这是一般的想法。

于 2015-09-05T08:43:43.563 回答