Angular-meteor ORM-like one-to-many relationship without infinite-digest issues -
i'm working on user-roles relationship, , code works except produces infinite digest error on angular side, think has performance implications. in user class (es2015), have:
get roles() { return roles.findbyids(this._roleids).fetch() }
and problem above getter returns new object every time, in angular's eyes, they're not equal. tried track by
, follows:
<ul> <li ng-repeat="role in user.roles track role._id"> {{role.name}} </li> </ul>
which throws following exception:
uncaught error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in 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}]]
without track by
, see longer stacktraces, mentioning "administrator"
error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in 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"}]]
so now, options avoiding getter, , having updateroles
method so:
updateroles() { this.roles = roles.findbyids(this._roleids).fetch() }
this gets rid of exception, seems have call updateroles
manually everytime _roleids
array changes. want know if there better approach compared have mentioned above.
the solution make getter idempotent. should return same roles array when given same _roleids
here's shot @ solving this. used idea similar github comment: https://github.com/angular/angular.js/issues/705#issuecomment-36737595
the idea define getter using object.defineproperty
or (es2015) reflect.defineproperty
, such getter idempotent.
reflect.defineproperty(this, "roles", { get: model._makeidempotent(this, "_roleids", () => { return roles.find({_id: {$in: this._roleids}}).fetch() }), })
though don't use above approach manually in own codes, , reflect.define...
gets called in loop every "foreign key", that's general idea.
Comments
Post a Comment