通用组件,在其中投影内容在外部区域实例化。

huangapple go评论69阅读模式
英文:

Generic component where projected content is instantiated in outer zone

问题

I understand your request. Here is the translated content:

我有一个 Web 组件,出于性能原因需要在 Angular 外部运行。

我想到了基本的方法:

@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 = // 设置输入
      })
   }
}

它可以正常工作,但不够通用,如果有多个 Web 组件要处理,会显得很繁琐。

是否可能构建一个自定义的通用组件,在其中投影的内容在外部区域运行?

英文:

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 ?

答案1

得分: 0

我最终编写了自己的指令来在NgZone之外运行特定组件。

受到NgIf工作原理的极大启发。

@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);
    }
  }
}

用法:

<my-cmp *runOutside></my-cmp>
英文:

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: &#39;[runOutside]&#39;,
  standalone: true,
})
export class RunOutsideDirective&lt;T&gt; {
  private isOutside: boolean;

  constructor(
    private _viewContainer: ViewContainerRef,
    private ngZone: NgZone,
    private templateRef: TemplateRef&lt;T&gt;
  ) {}

  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(() =&gt; {
        this._viewContainer.createEmbeddedView(this.templateRef);
      });
    } else {
      this._viewContainer.createEmbeddedView(this.templateRef);
    }
  }
}

usage :

&lt;my-cmp *runOutside&gt;&lt;/my-cmp&gt;

huangapple
  • 本文由 发表于 2023年4月13日 21:25:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76005994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定