Take a look at this simple Angular2 component:
@Component({
selector: 'status-area',
directives: [],
template: require('./status-area.tpl.jade')
})
export class StatusAreaComponent {
constructor(private _settings: SettingsProvider) {}
get items() {
return _.filter(this._settings.features, (feature: any) => {
return feature.inStatusBar && feature.isEnabled;
});
}
}
SettingsProvider has a property features, which is modified by another component (for example SettingsPanel). This components linked only by service (no input params).
So, as you have seen I need to fetch only enabled and marked as status-bar compatible features from _settings.features property.
For this purpose I use lodash method find.
However, as you might guess, angular throws an exception in development mode:
Expression has changed after it was checked
It happens because _.filter()
for each pass returns new instance of array, but collection is same.
My question is, how you solve this situation? Or may be there is another solution/approach to handle this case.
In my opinion it would be very useful if angular2 had special decorator like that:
@checkIterable()
get items() {
return _.filter(this._settings.features, (feature: any) => {
return feature.inStatusBar && feature.isEnabled;
});
}
Of course I can solve this by using another approach, with events and events listeners, but it produced a lot of boilerplate code.
Take a look at this example:
export class StatusAreaComponent implements OnInit, OnDestroy {
protected _items;
protected _removeWatcherFn;
constructor(private settings: SettingsProvider) {}
ngOnInit() {
this._items = this._fetchItems();
this._removeWatcherFn = this.settings.onChange.bind(() => {
this._items = this._fetchItems();
});
}
ngOnDestroy() {
this._removeWatcherFn();
}
_fetchItems() {
return _.filter(this.settings.features, (feature: any) => {
return feature.inStatusBar;
});
}
get items() {
return this._items;
}
}
In this way Angular is happy, but i don't.