Angular-类似流星 ORM 的一对多关系,没有无限摘要问题
Angular-meteor ORM-like one-to-many relationship without infinite-digest issues
我正在处理用户角色关系,我的代码可以正常工作,但它会在 Angular 端产生无限摘要错误,我认为这对性能有一些影响。在我的用户 class (ES2015) 中,我有:
get roles() {
return Roles.findByIds(this._roleIds).fetch()
}
而问题是上面的getter returns每次都是一个新对象,所以在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
,我看到更长的堆栈跟踪,提到 "Administrator"
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()
}
这消除了异常,但似乎每次 _roleIds
数组更改时我都必须手动调用 updateRoles
。我只是想知道是否有比我上面提到的更好的方法。
解决这个问题的方法是使 getter 幂等。当给定相同的 _roleIds
时,它应该 return 相同的 角色数组
这是我解决这个问题的方法。我使用了类似于此 Github 评论的想法:https://github.com/angular/angular.js/issues/705#issuecomment-36737595
想法是使用 Object.defineProperty
或 (ES2015) Reflect.defineProperty
定义 getter,这样 getter 将是幂等的。
Reflect.defineProperty(this, "roles", {
get: Model._makeIdempotent(this, "_roleIds", () => {
return Roles.find({_id: {$in: this._roleIds}}).fetch()
}),
})
虽然我没有在自己的代码中手动使用上述方法,并且 Reflect.define...
会在每个 "foreign key" 的循环中被调用,但这是一般的想法。
我正在处理用户角色关系,我的代码可以正常工作,但它会在 Angular 端产生无限摘要错误,我认为这对性能有一些影响。在我的用户 class (ES2015) 中,我有:
get roles() {
return Roles.findByIds(this._roleIds).fetch()
}
而问题是上面的getter returns每次都是一个新对象,所以在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
,我看到更长的堆栈跟踪,提到 "Administrator"
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()
}
这消除了异常,但似乎每次 _roleIds
数组更改时我都必须手动调用 updateRoles
。我只是想知道是否有比我上面提到的更好的方法。
解决这个问题的方法是使 getter 幂等。当给定相同的 _roleIds
这是我解决这个问题的方法。我使用了类似于此 Github 评论的想法:https://github.com/angular/angular.js/issues/705#issuecomment-36737595
想法是使用 Object.defineProperty
或 (ES2015) Reflect.defineProperty
定义 getter,这样 getter 将是幂等的。
Reflect.defineProperty(this, "roles", {
get: Model._makeIdempotent(this, "_roleIds", () => {
return Roles.find({_id: {$in: this._roleIds}}).fetch()
}),
})
虽然我没有在自己的代码中手动使用上述方法,并且 Reflect.define...
会在每个 "foreign key" 的循环中被调用,但这是一般的想法。