【问题标题】:Access directives of child components using ViewChildren使用 ViewChildren 访问子组件的指令
【发布时间】:2018-11-28 08:32:54
【问题描述】:

为了访问组件中的指令,我尝试了Angular 2: Get reference to a directive used in a component,但这不适用于组件子组件中的指令。

子组件是使用 ViewContainerRef 动态创建的。

 @ViewChildren(ViewRefDirective) allMyDirectives; 

//This doesn't work for directives in the child components

我有多个不同的子组件,这就是为什么我不能在 ViewChild 中指定单个子组件的名称来访问其指令。

指令

@Directive({
  selector: '[view-ref-host]',
})
export class ViewRefDirective {
  constructor(public viewContainerRef: ViewContainerRef) {
   }
}

父组件

<div>
  <div view-ref-host>Parent block
    <child-panel-one></child-panel-one>
    <child-panel-two></child-panel-two>
    <child-panel-three></child-panel-three>
  </div>
</div>

子面板一组件

<div>
  <div view-ref-host>Child panel one
    <!-- html here -->
  </div>
</div>

子面板二组件

<div>
  <div view-ref-host>Child panel two
    <!-- html here -->
  </div>
</div>

子面板三组件

<div>
  <div view-ref-host>Child panel three
    <!-- html here -->
  </div>
</div>

如何使用 ViewChild 装饰器访问父子组件中的所有指令?

【问题讨论】:

  • 显示完整代码
  • 父组件ts文件?
  • @fateme:我有 2000 行代码。不能分享。使用@ViewChildren(ViewRefDirective) allMyDirectives;在父组件中给我指令,但不包括子组件。
  • viewChildren 设置在ngAfterViewInit 可能你忘记了。
  • 如果在视图渲染后不使用它,我的父组件指令也不会加载。你应该已经猜到了。并且在渲染所有子级之前,父级的渲染不会完成。

标签: angular decorator angular-directive


【解决方案1】:

您可以在父组件中定义方法,例如:

allMyDirectives: ViewRefDirective[] = [];

registerRef(ref: ViewRefDirective) {
  this.allMyDirectives.push(ref);
}

并在指令的构造函数中注册指令:

@Directive({
  selector: '[view-ref-host]',
})
export class ViewRefDirective {
  constructor(
    public viewContainerRef: ViewContainerRef,
    @Optional() parent: AppComponent
  ) {
    if (parent) {
      parent.registerRef(this);
    }
  }
} 

Ng-run Example

【讨论】:

  • 这不会创建循环依赖吗?
【解决方案2】:

正确的实现方式是: @ViewChild("MyCustomDirective") allMyCustomDirectives;

【讨论】:

【解决方案3】:

您需要导出指令。然后只有您可以从父母或孩子那里使用它。然后从父级将其绑定到一个变量并使用视图子级访问该变量

@Directive({
  selector: '[view-ref-host]',
  exportAs:'viewRefDirective'  
})
export class ViewRefDirective {
  constructor(public viewContainerRef: ViewContainerRef) {
   }
}

<div>
  <div #cdire=viewRefDirective view-ref-host>Child panel one
    <!-- html here -->
  </div>
</div>

 @ViewChildren('cdire') allMyDirectives; 

更新

您可以使用QueryList 执行此操作。在每个 Child 中,添加组件

@ViewChildren('cdire') children: QueryList<ViewRefDirective>;

在父级中,级别添加

@ViewChildren('cdire') allMyDirectives; 
@ViewChild(childPanelOneComponent) c1: childPanelOneComponent;
@ViewChild(childPanelTwoComponent) c2: childPanelTwoComponent;
@ViewChild(childPanelThreeComponent) c3: childPanelThreeComponent;

ngAfterViewInit() {
    this.c1.children.forEach((child) => child.showChildName());
    this.c2.children.forEach((child) => child.showChildName());
    this.c3.children.forEach((child) => child.showChildName());
  }

【讨论】:

  • 不过,我只获取父组件的指令。它不适用于子组件。
  • 需要对子组件做同样的事情
  • 我已经在所有子组件的html中应用了#cdire=viewRefDirective。
  • 您是否也将@ViewChildren 添加到子组件中?
  • 不,因为我只需要在父级获取它们。这就是我的全部问题的全部内容。
猜你喜欢
  • 2020-06-08
  • 2018-10-05
  • 1970-01-01
  • 2020-04-10
  • 2022-11-21
  • 2019-09-08
  • 2016-12-26
  • 1970-01-01
  • 2020-05-30
相关资源
最近更新 更多