我希望构建一个组件,该组件使用Angular的componentFactoryResolver
和componentFactory
将组件动态注入到DOM上,但使用传入的viewContainerRef来确定可用于注入的内容。
@Component({
selector: 'my-component-loader',
template: ``
})
export class MyComponentLoader implements OnInit {
constructor(private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver,
private componentLoaderService: ComponentLoaderService) {
}
ngOnInit() {
this.componentLoaderService.loadComponent.pipe(
tap((component, componentViewContainerRef) => this.loadComponent(component, componentViewContainerRef))
).subscribe();
}
loadComponent(component, callerViewContainerRef) {
this.viewContainerRef.clear();
const factory = this.componentFactoryResolver.resolveComponentFactory(component);
this.viewContainerRef.createComponent(factory);
}
}
如何使用my-component-loader
的逻辑位置在callerViewContainerRef
位置内加载组件,以便创建的组件具有可用于callerViewContainerRef
的DI树。
简而言之,这类似于Material的MatDialog。
https://github.com/angular/components/blob/master/src/material/dialog/dialog-config.ts
有没有更简单的方法来处理而不复制Angular CDK门户逻辑?
**编辑**
这和传递callerViewContainerRef的注入器一样简单吗?
this.viewContainerRef.createComponent(factory, 0 , callerViewContainerRef.injector);
答案 0 :(得分:1)
这和传递callerViewContainerRef的注入器一样简单吗?
我认为这是正确的。这是我的另一个示例,它使我有了更好的理解。
export const FooToken = new InjectionToken('foo');
@NgModule({
/* ... */
providers: [
{
provide: FooToken,
useValue: { message: 'default foo value' }
}
]
})
export class AppModule { }
@Component({
selector: 'my-app',
template: `
<ng-container #vcr></ng-container>
`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('vcr', { static: true, read: ViewContainerRef })
vcr: ViewContainerRef;
ngAfterViewInit () {
const compFactory = this.cfr.resolveComponentFactory(FooComp);
const inj = Injector.create({
providers: [
{
provide: FooToken,
useValue: { message: 'this is just a foo message from a dynamic injector!' }
}
]
})
this.vcr.createComponent(compFactory, 0, inj);
}
}
@Component({
selector: 'foo',
template: `Foo!!`
})
export class FooComp {
constructor (@Inject(FooToken) private fooToken) {
console.log('[FOO]', this.fooToken)
}
}
如果按原样运行代码,则应该在Foo的构造函数中看到{ message: 'this is just a foo message from a dynamic injector!' }
。
但是,如果您在创建组件时未指定自定义注射器
this.vcr.createComponent(compFactory);
您应该看到以下内容:{ message: 'default foo value' }
您可以在我的playground
中找到上述想法。