1

I have a webcomponent that for perf reasons needs to run outside angular.

I came up with the basic idea :

@Component({
  selector: 'run-outer-zone',
  template: ''
}) 
class OuterZoneComponent {
   constructor(private vcr: ViewContainerRef, private ngZone: NgZone) {
      this.ngZone.runOutsideAngular(() => {
          const compRef = vcr.createComponent(MyComponentWhichNeedsToRunOutsideAngular);
          compRef.data = // set the inputs
      })
   }
}

It works fine but that's not very generic and it's cumbersome if have multiple web components to handle.

Is it possible to build a custom generic component where the projected content is run in the outer zone ?

Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134
  • What exactly do you want to do? Would you want `OuterZoneComponent` itself to be generic? Or do you want a generic method inside of `OuterZoneComponent` that runs the passed component outside of Angular? – Cuzy Apr 13 '23 at 13:39
  • I don't want to create 15 wrappers if I have 15 Web Components that need to be run outside angular ! – Matthieu Riegler Apr 13 '23 at 13:43

1 Answers1

0

I ended up writing my own directive to run specific components outside the NgZone.

It's hugely inspired by how the NgIf works.

@Directive({
  selector: '[runOutside]',
  standalone: true,
})
export class RunOutsideDirective<T> {
  private isOutside: boolean;

  constructor(
    private _viewContainer: ViewContainerRef,
    private ngZone: NgZone,
    private templateRef: TemplateRef<T>
  ) {}

  ngOnInit() {
    this.updateView(true);
  }

  @Input()
  set runOutside(doRunOutside) {
    this.updateView(doRunOutside);
  }

  private updateView(doRunOutside: boolean) {
    if (doRunOutside === this.isOutside) {
      return;
    }

    this._viewContainer.clear();
    if (doRunOutside) {
      this.ngZone.runOutsideAngular(() => {
        this._viewContainer.createEmbeddedView(this.templateRef);
      });
    } else {
      this._viewContainer.createEmbeddedView(this.templateRef);
    }
  }
}

usage :

<my-cmp *runOutside></my-cmp>
Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134