mobxjs / mobx-angular

The MobX connector for Angular.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature request: @Observer decorator

gevgeny opened this issue · comments

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.

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.

yeah, that the point.