动态加载 Angular 具有依赖项的组件
Dynamically load Angular component with dependencies
我一直在寻找一种干净的方式(不使用私有 API)解决小部件样式的仪表板。我想根据用户角色动态加载组件。
有没有办法动态导入组件模块中包含的组件和依赖项,这样的解决方案生产准备好了吗?
Stackblitz 再现:
欢迎任何对清洁解决方案的帮助。
编辑:我尝试使用 ViewContainerRef 解析组件,虽然解决方案有效(组件已呈现),但它只是附加到视图中,我希望能够获得具有已解析依赖项的组件的引用和将其传递到 *ngComponentOutlet 以便我可以使用 gridster 移动和调整组件大小。
我想你要找的是 ComponentFactoryResolver
。参考 this demo code
public render(): void {
const index = Math.round(Math.random());
const currentComponent = this.components[index];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(currentComponent as any);
let viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
let componentRef = viewContainerRef.createComponent(componentFactory);
}
我已经解决了!缺少的 link 是 ngModuleFactory 部分:
<ng-container
*ngComponentOutlet="widget.component; ngModuleFactory: widget.module"
></ng-container>
并且在 widget.service.ts 我已经解决了模块:
const { TasksWidgetModule } = await import('../tasks-widget/tasks-widget.module');
module = await this.compiler.compileModuleAsync(TasksWidgetModule);
我一直在寻找一种干净的方式(不使用私有 API)解决小部件样式的仪表板。我想根据用户角色动态加载组件。
有没有办法动态导入组件模块中包含的组件和依赖项,这样的解决方案生产准备好了吗?
Stackblitz 再现:
欢迎任何对清洁解决方案的帮助。
编辑:我尝试使用 ViewContainerRef 解析组件,虽然解决方案有效(组件已呈现),但它只是附加到视图中,我希望能够获得具有已解析依赖项的组件的引用和将其传递到 *ngComponentOutlet 以便我可以使用 gridster 移动和调整组件大小。
我想你要找的是 ComponentFactoryResolver
。参考 this demo code
public render(): void {
const index = Math.round(Math.random());
const currentComponent = this.components[index];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(currentComponent as any);
let viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
let componentRef = viewContainerRef.createComponent(componentFactory);
}
我已经解决了!缺少的 link 是 ngModuleFactory 部分:
<ng-container
*ngComponentOutlet="widget.component; ngModuleFactory: widget.module"
></ng-container>
并且在 widget.service.ts 我已经解决了模块:
const { TasksWidgetModule } = await import('../tasks-widget/tasks-widget.module');
module = await this.compiler.compileModuleAsync(TasksWidgetModule);