1

For accessing the directives in a component, I have tried Angular 2: Get reference to a directive used in a component but this doesn't work for directives in the child components of the component.

The child components are created dynamically using ViewContainerRef.

 @ViewChildren(ViewRefDirective) allMyDirectives; 

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

I have multiple different child components, that's why I can't specify the name of a single child component in ViewChild for accessing its directives.

Directive

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

Parent component

<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>

Child panel one component

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

Child panel two component

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

Child panel three component

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

How can I use the ViewChild decorator to access all the directives in parent and child component?

Prachi
  • 3,478
  • 17
  • 34

3 Answers3

3

You can define method in your parent component like:

allMyDirectives: ViewRefDirective[] = [];

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

and register directive in directive's constructor:

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

Ng-run Example

yurzui
  • 205,937
  • 32
  • 433
  • 399
0

The correct way to implement is: @ViewChild("MyCustomDirective") allMyCustomDirectives;

  • See the updated question. ViewRefDirective is the name of my directive. It is not a selector, but the directive name. See https://angular.io/guide/dynamic-component-loader#resolving-components – Prachi Jun 19 '18 at 11:40
0

you need to export the directive. Then only you can use it from parent or child. Then from parent bind it to a variable and access that variable using view child

@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; 

Update

you can do this using QueryList. in each Child, components add

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

In the parent, level add

@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());
  }
Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80