2016-11-25 107 views
1

我有一些代码可以动态地将组件添加/删除到我的某个页面。这似乎工作正常,我基于Rob Wormald的真棒Ng2 Advanced Talk的方法。在ngIf中动态添加组件

做在标准的方式事情是这样的:

@Component({ 
    template: ` 
    <parent-component> 
     <template #dyn_target></template> 
    </parent-component> 
    ` 
}) 
export class MyComp { 
    @ViewChild('dyn_target', {read: ViewContainerRef}) myTarget; 

    constructor(protected cfr: ComponentFactoryResolver) {} 

    ngOnInit(): void { 
     const factory = this.cfr.resolveComponentFactory(DynComp); 
     const compRef = this.myTarget.createComponent(factory); 
    } 
} 

一切都是快乐而工作。但现在我的问题是,如果组件的目标位置是一个本身位于* ngIf内部的元素,我该如何做这样的事情?我有知道* ngIf应该显示新元素的代码,但是我不知道如何在* ngIf内查找目标的ViewContainerRef。

@Component({ 
    template: ` 
    <parent-component> 
     <other-comp></other-comp> 
     <div *ngIf="showMe" 
      <nested-comp> 
       <template #dyn_target></template> 
      </nested-comp> 
     </div> 

    </parent-component> 
    ` 
}) 
export class MyComp { 
    @ViewChild('dyn_target', {read: ViewContainerRef}) myTarget; 
    showMe: boolean = false; 

    constructor(protected cfr: ComponentFactoryResolver) {} 

    addDynComponent(): void { 
     // Q: how do I do this?   vv 
     const target: ViewContainerRef = lookup('dyn_target'); 
     const factory = this.cfr.resolveComponentFactory(DynComp); 
     const compRef = target.createComponent(factory); 
    } 
} 

我想过尝试删除ngIf,使整个街区充满活力,但并没有真正对我的情况下工作,因为大部分的内容是静态的,只有一个子组件需要添加何时/如果ngIf为真。

任何人都知道如何在ngIf将其他元素添加到DOM之后随时查找ViewContainerRef?

注意:另一种我认为这样做的方式是添加一个新的组件类型,该组件类型仅基于组件类类型的输入显示嵌套组件。我已经看到了为Ionic 2完成的这种类型的事情,它可能适用于我的情况,但似乎是矫枉过正。因此,像:

@Component({ 
    template: ` 
    <parent-component> 
     <other-comp></other-comp> 
     <div *ngIf="showMe" 
      <nested-comp> 
       <show-comp [compClass]="dynClass"></show-comp> 
      </nested-comp> 
     </div> 

    </parent-component> 
    ` 
}) 
export class MyComp { 
    dynClass: any; 
    showMe: boolean = false; 

    addDynComponent(): void { 
     dynClass = DynComp; 
    } 
} 

回答

3

我认为这应该工作

@ViewChildren('dyn_target', {read: ViewContainerRef}) myTarget:QueryList<ViewContainerRef>; 

ngAfterViewInit() { 
    this.myTarget.changes.subscribe(changes => { 
    if(this.myTarget.toArray().length) { 
     // myTarget ViewContainerRef available 
    } 
    }); 
} 
+1

权,固定。谢谢。 –

+0

有没有什么办法直接运行视图查询而不使用@ViewChildren属性修饰器?我一直在试图找到ViewChildren调用来执行此查询的代码,但没有多少运气。 :( – Allen

+0

不要这么想,我想这是编译器的一部分。 –