通过父组件

时间:2016-12-02 11:56:59

标签: angular web-component

我想知道是否可以在Angular 2中执行以下操作。拥有一个包含此模板的组件(例如):

ParentComponent模板

<div>
  <childOne></childOne>

  <childTwo *ngFor="let item of items">
    whatever
  </childTwo>
</div>

有没有办法使用ParentComponent中的ViewContainerRef删除这些项目,如下所示?

var viewContainerRef = /* get ParentComponent ViewContainerRef */
var index = viewContainerRef.indexOf(childViewRef);
viewContainerRef.remove(index);

我尝试使用类似于此处提议的解决方案来检索子ViewRef: Angular2 , How to find index of a view inside a viewContianer

但是indexOf返回-1,好像容器中没有子ViewRef。

我想删除ParentComponent之外的这些子组件,而不是在ParentComponent代码中删除,例如从items数组中删除或通过绑定删除。

我也尝试使用Renderer中的destroyView方法,但没有效果。 NgFor正在迭代items数组并为每个childTwo创建嵌入视图,在这种情况下,如果从ChildTwo注入器获得的ViewRef(如链接解决方案中所提出的)与这些EmbeddedViewRef相同,我不会这样做。

有没有办法做那样的事情?

谢谢。

***********************更新*********************** ****

我会尽量简化我想要实现的目标。我正在开发一个仪表板,用户可以使用以下API创建其组件:

@Component({ selector: 'child' })
class UserChildComponent extends DashboardComponent {
  (...)
}

@Component({ selector: 'parent' })
class UserParentComponent extends DashboardComponent {

  @ViewChildren(UserChildComponent) m_children: QueryList<UserChildComponent>;

  private models: Array<ChildModel>;

  (...)
}

/* UserParentComponent template
<div>
  <child></child>
  <child *ngFor="let model of models"></child>
</div>

我有一个所有Dashboard组件的逻辑树及其相互之间的关系(父/子),因为子类型和其他东西在这里没有关注的场景。

这是我想到的场景:用户可以删除任何这些子仪表板组件。我想,在需要所有关系树的情况下,将子项从父项中删除并通知用户(可能通过父项中的ViewChildren)。或者我实际上可以在父级上调用方法,以便用户可以更新其模型数组,这可能是最好的方法。

我只想到一种方式,用户可以减少工作量,不必担心同步模型\组件(在这种情况下)

再次感谢。

2 个答案:

答案 0 :(得分:1)

您可以使用

let element = querySelector(...);
element.parentNode.removeChild(element)

但是不鼓励在Angular2中使用直接DOM访问。 Angular2本身不提供您想要的API。 在Angular2中,您应该只更新模型并让Angular执行DOM操作。

答案 1 :(得分:1)

我能想到的一个可能的解决方案是创建一个具有如下事件发射器的服务:

export class ChildRemoveNotifierService{

     public $remove = new EventEmitter<string>();

}

然后,我们需要一个可以删除元素并创建它们的指令:

 @Directive({ selector: '[remover]' })
export class RemoveDirective {

  @Input remove = '';
  constructor(
    private removerService:ChildRemoveNotifierService ,
    private _templateRef: TemplateRef,
    private _viewContainer: ViewContainerRef
    ) {


          let subscription =
          this.removerService.$remove.subscribe((tobeRemoved)=>{
             if(tobeRemoved===this.remove){
                 this._viewContainer.clear();
                 subscription.unsubscribe();
             }
          })
    }

然后,你可以这样使用:

 <span *remover='my-component'>
     <my-component></my-component>
 </span>

基本上,任何需要动态删除的组件都应该用* remover指令包装。

然后,现在,everyOne可以删除所有人:)

您的父组件可以触发这样的事件:

export class ParentComponentOrAnyOther{

     constructor(private removerService:ChildRemoveNotifierService){

      }

      removeAComponent(){

          removerService.$remove.emit('my-component');

      }
}

这不太理想,或者可能是,我不知道。

但我确实知道这绝对是Angular方式而你没有做任何DOM操作。

这样,您拥有所有Angular2生命周期,特别是onDestroy事件将在my-component中触发。

编辑:

我认为这也会奏效:

  <my-component *remover='my-component'></my-component>