我有一个案例,我在列表中动态创建组件(刷新很多)并使用ngSwitch
这样:
<div *ngFor='let item of items'>
<div [ngSwitch]="item.view">
<view-one *ngSwitchCase="'one'"></view-one>
<view-two *ngSwitchCase="'two'"></view-two>
<view-three *ngSwitchCase="'three'"></view-three>
</div>
</div>
我想知道是否有更好的更有效的方法,或者这是正确的方法吗?
我已经看到人们动态创建组件,但是api已经改变了很多次,很难知道什么是正确的。看来ViewContainerRef.createComponent()
可能是替代方案吗?
答案 0 :(得分:5)
我更喜欢...
AtomicInteger pos = new AtomicInteger(0);
AtomicInteger split = new AtomicInteger(batchLength);
Map<Integer, List<Integer>> map = integerList.stream()
.collect(Collectors.groupingBy(e -> Integer.valueOf(pos.getAndIncrement() / split.get())));
而不是createComponent()
,因为我认为它更容易测试和扩展。我还没有看到任何表现不足。
这是我目前方法的简化形式:
ngSwitch
现在您可以通过以下方式使用它:
@Component({
selector: "my-item",
template: `
<div #placeholder></div>
`
})
export class MyItemComponent implements AfterViewInit {
@Input() item: any;
@ViewChild("placeholder", {read: ViewContainerRef}) placeholderRef: ViewContainerRef;
constructor(
private componentFactoryResolver: ComponentFactoryResolver) {
}
ngAfterViewInit() {
switch(this.item.view) {
case "one":
this.loadItem(OneItemComponent);
case "two":
this.loadItem(TwoItemComponent);
default:
throw new Error("Unknown item!");
}
}
private loadItem(component: Type<any>) {
const factory = this.componentFactoryResolver.resolveComponentFactory(component);
const componentRef = this.placeholderRef.createComponent(factory);
componentRef.instance.item = this.item;
componentRef.changeDetectorRef.detectChanges();
}
}
答案 1 :(得分:2)
以下是我在应用中实施动态组件的方法:
export class DynamicComponent implements AfterViewInit, OnChanges, OnDestroy {
@Input() model: any;
@Input() factory: ComponentFactory<any>;
@ViewChild('target', { read: ViewContainerRef }) target: any;
private initialized: boolean = false;
private componentRef: ComponentRef<any>;
private updateComponent() {
if (!this.initialized || !this.factory) {
return;
}
if (this.componentRef) {
this.componentRef.destroy();
}
this.componentRef = this.target.createComponent(this.factory);
this.componentRef.instance.model = this.model;
this.componentRef.changeDetectorRef.detectChanges();
}
ngOnChanges() {
this.updateComponent();
}
ngAfterViewInit() {
this.initialized = true;
this.updateComponent();
}
ngOnDestroy() {
if (this.componentRef) {
this.componentRef.destroy();
}
}
}
要使其工作,您需要一个包含
的模板<div #target><div>
对于这个类,它将出现动态创建的组件。
以下是它的使用方式:
<dynamic [factory]="myFactory" [model]="myModel"></dynamic>
myFactory
是ComponentFactory
,例如
let factory = this.resolver.resolveComponentFactory(MyComponent);
其中resolver
是ComponentFactoryResolver
(来自@angular/core
)。
myModel
是您可以传递给新创建的组件的数据,并且可以作为@Input()
参数使用。