动态实例化,更新和删除组件

时间:2018-08-17 08:50:59

标签: angular

我刚刚开始为一个小型玩具项目陷入困境,并在组件的动态初始化过程中遇到了一些问题。

我有几个不同的组件都实现了一个接口,该接口为它们提供了基本属性,例如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();
});

我能够识别“盒子状态有变化” ,但是我看不到哪个对象受到了影响,所有盒子的重新初始化似乎都不像一个很好的解决方案。

还是我的方法不对? (更好的方法是什么样的?)

预先感谢

0 个答案:

没有答案