Sne*_*ike 3 forms multiple-instances angular-components angular angular-dynamic-components
\nI\xe2\x80\x99m 尝试动态加载同一组件的多个实例,当用户提交表单时,新组件将添加/加载到屏幕上。其背后的想法是,用户可以提供表单的详细信息,然后将其显示在所创建的组件的特定实例上。
\n我最初的想法是拥有某种数据结构,例如键对值的数组或映射,这样当用户提交表单时,我可以将组件的新实例与表单数据一起添加到我的数据结构中。然后 Angular 可以以某种方式显示驻留在数据结构中的组件的每个实例,如下图所示:
\n\n需要注意的是,该表单实际上是它自己的独立组件,以模式对话框的形式存在。当按下绿色的“添加状态框”按钮时,将打开此表单对话框,然后用户可以提交表单并(希望)能够使用提交的表单提供的数据创建状态框组件的新实例。
\n然而这被证明是困难的,目前我\xe2\x80\x99m 在上面的屏幕截图中实现这一点的方法是仅在 app.component.html 中单独显示每个组件,它根本不是动态的,并且具有无用户控制:
\n<app-header></app-header>\n<div class=\'status-box-container\'>\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n</div>\n我\xe2\x80\x99已经遵循了一些教程,但是所述教程的结果\xe2\x80\x99t完全不符合我\xe2\x80\x99m的要求,\xe2\x80\x99根本不起作用,或者它\xe2\x80\x99 对我来说太复杂了,无法理解。
\n首先,我尝试遵循Angular 网站上的官方指南,但这一次仅显示一个组件,并且每 3 秒动态更改其内容,而不是同时显示一个组件的多个实例。
\n接下来,我尝试从这个现有的堆栈溢出问题中跟踪这个 stackblitz,但我发现这不起作用并且非常复杂,其中大部分我不理解\xe2\x80\x99。尽管它\xe2\x80\x99s非常接近我\xe2\x80\x99m试图实现的目标。
\n最后,我尝试遵循我发现的 stackblitz,但它\xe2\x80\x99s 并不像我希望的那样动态,因为组件的每个实例都被硬编码到不同的变量中,我也无法让它工作。
\n但我注意到的一件事是,所有三种方法都有两个共同点。首先在app.component.html中,他们使用<ng-container #messageContainer></ng-container>或<ng-template #messageContainer></ng-template>。据我了解,这是将动态组件加载到 html 模板中的地方。
app.component.ts 中的第二部分通常如下所示:
\n@ViewChild(\'messageContainer\', { read: ViewContainerRef, static: true })\nmessageContainer: ViewContainerRef;\n\nconstructor (private cfr: ComponentFactoryResolver) { }\n\nprivate createComponent (compClass) \n{\n  const compFactory = this.cfr.resolveComponentFactory(compClass);\n  return this.messageContainer.createComponent(compFactory);;\n}\n\nprivate loadNewComponentList () \n{\n  this.messages.forEach((msg, idx) => \n  {\n    this.destroyCompFromList(this.componentList[idx]);\n    const comp = this.createComponent(componentMap[this._crtComp]);\n\n    (comp.instance as any).message = msg;\n\n    comp.changeDetectorRef.detectChanges();\n\n    this.componentList[idx] = comp;\n  });\n}\n现在我不\xe2\x80\x99真正理解这段代码的作用,但从它的角度来看,它似乎ComponentFactoryResolver负责创建相同组件的多个实例。似乎ViewContainerRef是 html 模板中使用的\xe2\x80\x99s。
这似乎是我应该前进的方向,但我不了解这些导入的类的作用,而且我什至不确定这种方法是否适合我的特定要求。
\n我希望有人可以向我展示一个简单的解决方案来解决这个问题,或者至少调整/简化教程以满足我的特定要求。
\n谢谢。
\n小智 5
你走在正确的轨道上。简单总结一下Angular 的官方指南,您应该创建一个指令来轻松获取ViewContainerRefHTML 元素 - 该组件将作为其同级组件注入。然后使用ComponentFactoryResolver在需要时用于创建您的组件。
就个人而言,指令还负责创建组件,因为它允许您轻松地将其与*ngFor常规组件一起使用并将所有动态内容与常规组件分开
@Directive({
    selector: '[appDynamicStatusBox]'
})
export class DynamicStatusBoxDirective implements OnInit, OnDestroy {
    @Input() config: MyData;
    componentRef: ComponentRef<StatusBoxComponent>;
    constructor(private resolver: ComponentFactoryResolver, public viewContainerRef: ViewContainerRef) {}
    ngOnInit(): void {
        const factory = this.resolver.resolveComponentFactory(StatusBoxComponent);
        this.viewContainerRef.clear();
        this.componentRef = this.viewContainerRef.createComponent(factory);
        this.componentRef.instance.someProperty= this.config.prop1;
        this.componentRef.instance.someOtherProperty= this.config.prop2;
    }
    ngOnDestroy(): void {
        this.componentRef.destroy();
    }
}
<ng-container *ngFor="let config of myConfigs; let i=index" appDynamicStatusBox [config]="config[i]"></ng-container>
| 归档时间: | 
 | 
| 查看次数: | 4993 次 | 
| 最近记录: |