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

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

Generic component where projected content is instantiated in outer zone

问题

I understand your request. Here is the translated content:

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

我想到了基本的方法:

  1. @Component({
  2. selector: 'run-outer-zone',
  3. template: ''
  4. })
  5. class OuterZoneComponent {
  6. constructor(private vcr: ViewContainerRef, private ngZone: NgZone) {
  7. this.ngZone.runOutsideAngular(() => {
  8. const compRef = vcr.createComponent(MyComponentWhichNeedsToRunOutsideAngular);
  9. compRef.data = // 设置输入
  10. })
  11. }
  12. }

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

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

英文:

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

I came up with the basic idea :

  1. @Component({
  2. selector: 'run-outer-zone',
  3. template: ''
  4. })
  5. class OuterZoneComponent {
  6. constructor(private vcr: ViewContainerRef, private ngZone: NgZone) {
  7. this.ngZone.runOutsideAngular(() => {
  8. const compRef = vcr.createComponent(MyComponentWhichNeedsToRunOutsideAngular);
  9. compRef.data = // set the inputs
  10. })
  11. }
  12. }

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工作原理的极大启发。

  1. @Directive({
  2. selector: '[runOutside]',
  3. standalone: true,
  4. })
  5. export class RunOutsideDirective<T> {
  6. private isOutside: boolean;
  7. constructor(
  8. private _viewContainer: ViewContainerRef,
  9. private ngZone: NgZone,
  10. private templateRef: TemplateRef<T>
  11. ) {}
  12. ngOnInit() {
  13. this.updateView(true);
  14. }
  15. @Input()
  16. set runOutside(doRunOutside) {
  17. this.updateView(doRunOutside);
  18. }
  19. private updateView(doRunOutside: boolean) {
  20. if (doRunOutside === this.isOutside) {
  21. return;
  22. }
  23. this._viewContainer.clear();
  24. if (doRunOutside) {
  25. this.ngZone.runOutsideAngular(() => {
  26. this._viewContainer.createEmbeddedView(this.templateRef);
  27. });
  28. } else {
  29. this._viewContainer.createEmbeddedView(this.templateRef);
  30. }
  31. }
  32. }

用法:

  1. <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.

  1. @Directive({
  2. selector: &#39;[runOutside]&#39;,
  3. standalone: true,
  4. })
  5. export class RunOutsideDirective&lt;T&gt; {
  6. private isOutside: boolean;
  7. constructor(
  8. private _viewContainer: ViewContainerRef,
  9. private ngZone: NgZone,
  10. private templateRef: TemplateRef&lt;T&gt;
  11. ) {}
  12. ngOnInit() {
  13. this.updateView(true);
  14. }
  15. @Input()
  16. set runOutside(doRunOutside) {
  17. this.updateView(doRunOutside);
  18. }
  19. private updateView(doRunOutside: boolean) {
  20. if (doRunOutside === this.isOutside) {
  21. return;
  22. }
  23. this._viewContainer.clear();
  24. if (doRunOutside) {
  25. this.ngZone.runOutsideAngular(() =&gt; {
  26. this._viewContainer.createEmbeddedView(this.templateRef);
  27. });
  28. } else {
  29. this._viewContainer.createEmbeddedView(this.templateRef);
  30. }
  31. }
  32. }

usage :

  1. &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:

确定