Feature request: @Observer decorator
gevgeny opened this issue · comments
Eugene Gluhotorenko commented
Hello!
What about adding one more possibility to react on observables in components. Just like in mobx-react we can add decorator:
@Observer()
@Component({
selector: 'app-user',
template: `
<div>{{store.firstName}} {{store.secondName}}<div>
`,
})
export class ListComponent {
constructor(
public store: MyStore
private injector: Injector, // needed for running changes detection in from the decorator
) { }
}
The implementation is pretty straightforward and it has the same idea as the autorun directive:
export function Observer(): ClassDecorator {
return function (constructor: any) {
const ngOnInit = constructor.prototype.ngOnInit;
const ngOnDestroy = constructor.prototype.ngOnDestroy;
constructor.prototype.ngOnInit = function (...args) {
if (!this.injector) {
throw new Error(`Injector is not initialized in the "${this.constructor.name}" component`);
}
const changeDetector = this.injector.get(ChangeDetectorRef);
const name = `${this.constructor.name}.detectChanges()`;
this.disposeAutorun = autorun(
() => {
changeDetector.detectChanges();
}, { name }
);
ngOnInit && ngOnInit.apply(this, args);
};
constructor.prototype.ngOnDestroy = function (...args) {
this.disposeAutorun();
ngOnDestroy && ngOnDestroy.apply(this, args);
};
};
}
I can create PR if you decide this is a good idea.
Adam Klein commented
This is how the library started, but I was trying to avoid forcing the user to inject something artificially into the component in order for the library to work.
Eugene Gluhotorenko commented
yeah, that the point.