如何从ViewContainer角度删除特定视图

时间:2018-08-09 10:32:08

标签: angular

在下面的示例中,https://stackblitz.com/edit/angular-1acvol

我已经使用TemplateRef创建了多个视图,并将它们附加到相同的ViewContainer。但是我无法弄清楚如何从View中删除特定的ViewContainer

我知道ViewContainerRef中有诸如removedetachindexOf之类的方法,但是我找不到使用它们的方法。

我的模板是

  <ng-template #thumbnailTemplate let-description="description">
    <div>
      <a href="#" (click)="deleteView()">Delete {{description}}} (</a>
    </div>
  </ng-template> 

HTML是

<button #showTmplButton (click)="showTemplate()">{{buttonTitle}} </button>
<ng-container #vc></ng-container>

点击button后,模板的新实例将添加到ng-container中。我希望在单击a时删除该特定视图。但是我怎么知道视图存储在ViewContainer的哪个索引上以及如何将其传递给deleteView函数呢?

添加视图的逻辑是

  showTemplate(){  

    let view:ViewRef = this.vc.createEmbeddedView(this.tmpl, {description: 'description '+(this.id++)}) 

  }

但是我不删除特定视图

deleteView(){
    /*what to do here.  
    this.vc.remove(...);
    */

     }

1 个答案:

答案 0 :(得分:0)

这似乎有效。我正在尝试从容器中删除视图,但是我需要删除该视图的引用。

我学到的新东西很少

创建视图时,我们可以传递一个上下文对象。就像传递到模板的数据一样(将其视为参数,而模板是函数)。

let view:ViewRef = this.vc.createEmbeddedView(this.tmpl, 
   {option:{divId:'thumbnail-'+(this.divId++),
    closeId:'close-'+(this.closeId++)
    }} );

如果模板是

 <ng-template #thumbnailTemplate let-option="option"  let-index="index">
    <div id="{{option.divId}}"> 
      <img> 
      <a href="#" id="{{option.closeId}}" (click)="deleteIt(option)">template  inserted at index {{option.index}}, {{option.divId}}, {{option.closeId}}</a>

    </div>
  </ng-template> 

然后让选项与option:匹配,{option:{divId:'thumbnail-'+(this.divId++), closeId:'close-'+(this.closeId++)}}是上下文对象,然后我可以在模板中将option用作{{option.divId}}。此处说明-What is $implicit in angular 2?

一旦我学会了如何向模板传递数据,就想到使用createEmbeddedView并将index传递给模板,然后再用索引值更新视图的上下文对象。然后,我以后可以检索该值,并在remove的{​​{1}}中使用它来删除该视图。最初似乎可行,但在我存储了视图0、1、2、3然后删除了索引1之后,容器将重新组织视图并为其分配新索引。但是,上下文对象中的值没有更新。

因此,我没有存储索引,而是将ngContainerRef存储在上下文对象中,并且当我要删除视图时,我调用ViewRef来获取正确的索引值并将其用于{{1 }}

代码。

indexOf

在html中,模板获取选项对象,并且remove的{​​{1}}回调将其传递给 showTemplate(){ /* You need to pass an object with the keys that match the let-keyname syntax: The ng-template in html uses let-option and let-index so the object passed need to have index and option keys */ //create view and pass context data let view:ViewRef = this.vc.createEmbeddedView(this.tmpl, {option:{divId:'thumbnail-'+(this.divId++), closeId:'close-'+(this.closeId++) }} ); //after view is created, get its index and updat context. Note that ViewIndexRef was not in initial context object. view.context.option.viewIndexRef = view;//store ref of this view } //pass the entier context object to the function deleteIt(option){ //get viewRef from context and then get index of the viewref let index = this.vc.indexOf(option.viewIndexRef) //remove the view this.vc.remove(index); } 函数

click