我正在尝试动态加载多个组件,并且一次只能看到其中一个组件。基本上我正在构建一个可能有100个或更多组件的应用程序,我想在运行时将这些组件的子集动态加载到我的应用程序中。我只希望一次查看其中一个组件,但我希望每个加载的组件都保留在DOM中,以便用户可以在每个选项卡上进行编辑,而不会在更改选项卡时丢失更改。我试图使用动态组件加载和ViewComponentRef抽象类来实现它。由于我希望所有加载的组件都保留在DOM中,直到我删除它们为止,因此我创建了两个容器组件并计划隐藏其中一个组件。第二个容器组件将只包含我想要显示的已加载组件。我尝试使用主集合上的get()方法和所选集合上的insert()方法执行此操作。代码运行没有错误,但它没有按我的预期执行。它不会将实际组件内容(即html)从主集合复制到所选集合。如何将视图从一个集合复制到另一个集合,并且有一种不同的方式只显示动态加载的组件的子集。
打字稿
import { Component, Input, Output, EventEmitter, ComponentFactoryResolver, AfterViewInit, OnDestroy, ViewChild,Type, ViewContainerRef } from '@angular/core';
import { AppletContainer } from '../appletContainer/appletContainer.component';
import { AppletCollection } from '../appletCollection/appletCollection.component';
import { AdComponent } from '../ad.component';
import { TestComponent } from '../test.component';
export class AdItem {
constructor(public component: Type<any>, public data: any) {}
}
@Component({
selector: 'applet-frame',
templateUrl: '/NetworkDesigner2/views/app/appletFrame/appletFrame.component.html',
styleUrls: ['NetworkDesigner2/views/app/appletFrame/appletFrame.component.css'],
entryComponents:[TestComponent]
})
export class AppletFrame implements AfterViewInit, OnDestroy {
items: AdItem[] = [];
@Input() inputControlStructure:any;
@Output() updateControlStructure = new EventEmitter<any>();
currentIndex: number = 0;
counter:number = 0;
@ViewChild(AppletContainer) adHost: AppletContainer;
@ViewChild(AppletCollection) master: AppletCollection;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
let newItem = new AdItem(TestComponent,{component:'sample manual component',description:'sample manaual component'})
this.items.push(newItem);
}
ngAfterViewInit(){
}
ngOnDestroy(){}
loadComponent(){
// Identify the current target component to load
let adItem = this.items[this.currentIndex];
// Create the component Factory object for the target component
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
// Declare a reference to the viewContainerRef object for the 'master' collection. This is the ng-template that will be hidden
let viewContainerRef1 = this.adHost.viewContainerRef;
// Declare a reference to the viewContainerRef object for the 'select' collection. This is the collection that will show the selected component
let viewContainerRef2 = this.master.viewContainerRef;
// Create the component
viewContainerRef1.createComponent(componentFactory);
// Clear the 'select' container so that I can copy over the targeted view only
viewContainerRef2.clear();
// Copy the targeted view into the 'select' container. For now this is hardcoded to copy the first element as an experiment
viewContainerRef2.insert(viewContainerRef1.get(0),0);
this.counter++;
}
loadSampleContentHandler(){
this.loadComponent();
}
}
基本的html文件
<div class="l_appletFrame t_appletFrame" [ngClass]="{'l_extendedFrame':!inputControlStructure.summaryViewVisible}">
<div class="l_appletBanner t_appletBanner" >
<div class="l_revisionTypeContainer t_revisionTypeContainer">
<div class="l_revisionLabel">Revision Type:</div>
<div class="l_revisionTypeName">{{inputControlStructure.activeRevisionType}}</div>
</div>
<div class="l_buttonContainer">
<div class="l_button t_button"><div class="l_textBox" (click)="loadSampleContentHandler()">Load</div></div>
<div class="l_button t_button"><div class="l_textBox">Submit</div></div>
<div class="l_button t_button"><div class="l_textBox">Close</div></div>
</div>
</div>
<div class="l_appletContainer" [ngClass]="{'l_extendedContainer':!inputControlStructure.summaryViewVisible}">
<!-- <router-outlet name="primary"></router-outlet>
<router-outlet name="simple"></router-outlet> -->
<!-- <sample-applet></sample-applet> -->
<div class="l_collection"><ng-template applet-collection></ng-template></div>
<div class="l_container"><ng-template applet-container></ng-template></div>
</div>
</div>