我刚刚开始为一个小型玩具项目陷入困境,并在组件的动态初始化过程中遇到了一些问题。
我有几个不同的组件都实现了一个接口,该接口为它们提供了基本属性,例如ID,Name等。
应用程序应显示其中的某些组件,如果应用程序状态发生变化,则应将这些组件中的某些与其他组件交换,以实现相同的界面。
标记:
<ng-template ngFor let-area [ngForOf]="d.boxes" let-index="index">
<ng-template #boxComponent></ng-template>
</ng-template>
模板的初始化如下:
export class BoxesDemoComponent implements OnInit, AfterViewInit {
@ViewChildren('boxComponent', { read: ViewContainerRef })
boxTargets: QueryList<ViewContainerRef>;
constructor(private componentFactoryResolver: ComponentFactoryResolver,
private cdRef: ChangeDetectorRef,
private aRef: ApplicationRef) { }
ngOnInit() {
const firstArea = this.addArea();
firstArea.type = MenuBoxComponent;
this.selected(this.d.boxes[0]);
for (let i = 0; i < this.boxTargets.toArray().length; i++) {
const target = this.boxTargets.toArray()[i];
this.initArea(target, this.d.boxes[i], MenuBoxComponent);
}
}
ngAfterViewInit() {
this.boxTargets.changes.subscribe(_ => {
console.log('this.boxTargets.changes.subscribe');
const idx = this.boxTargets.toArray().length - 1;
const target = this.boxTargets.toArray()[idx];
this.initArea(target, this.d.boxes[idx], this.d.boxes[idx].type);
this.cdRef.detectChanges();
});
}
initArea(vcRef: ViewContainerRef, curArea: Area, componentType) {
const widgetComponent: ComponentFactory<ComponentRef> = this.componentFactoryResolver.resolveComponentFactory(componentType);
vcRef.clear();
const cmpRef: ComponentRef<BaseBoxComponent> = vcRef.createComponent(widgetComponent);
cmpRef.instance.area = curArea;
cmpRef.instance.boxes = this.d.boxes;
}
}
使用这种方法大致可以正常工作:我可以重新实例化类型为box.type
的盒子,但是我只想重新实例化那些盒子,而不是全部实例,但是我无法确定携带了哪个对象实例由ViewContainerRef
。
有没有办法找出答案?
我的失败点位于这里:
this.boxTargets.changes.subscribe(_ => {
console.log('this.boxTargets.changes.subscribe');
const idx = this.boxTargets.toArray().length - 1;
const target = this.boxTargets.toArray()[idx];
this.initArea(target, this.d.boxes[idx], this.d.boxes[idx].type);
this.cdRef.detectChanges();
});
我能够识别“盒子状态有变化” ,但是我看不到哪个对象受到了影响,所有盒子的重新初始化似乎都不像一个很好的解决方案。
还是我的方法不对? (更好的方法是什么样的?)
预先感谢