英文:
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: '[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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论