I am trying to implement some features in my angular application. I have created a parent directive appParent
and two other directives appChildAbc
and appChildXyz
.
What I want to do is that whenever I have the appParent
directive applied on an element, I want to check for its child elements (native HTML elements in the same component) and apply some logic to these child elements.
After much search and struggle I have found a way to do it using the ViewContainerRef
in ParentDirective
and @ViewChildren
in AppComponent
, but I had to use ((this.viewContainerRef as any)._view.nodes)
, which does not look like the right way to do it.
Is there any other way to get the reference of Child Elements
in the parent directive ??
Sample stackblitz here
Feel free to fork the code and update as necessary. Thanks in advance
export class ParentDirective {
constructor(private vcr: ViewContainerRef) {}
ngAfterViewInit() {
console.log((this.vcr as any)._view.nodes);
let lists = (this.vcr as any)._view.nodes.filter(
x => x.constructor.name === "QueryList"
);
lists.forEach(list => {
list.toArray().forEach(x => {
if (x.constructor.name === "ChildXyzDirective")
x.elementRef.nativeElement.style.background = "red";
else x.elementRef.nativeElement.style.background = "green";
console.log(x);
});
});
}
}
export class AppComponent {
name = 'Angular';
@ViewChildren(ChildXyzDirective) xyzChildren: QueryList<ChildXyzDirective>;
@ViewChildren(ChildAbcDirective) abcChildren: QueryList<ChildAbcDirective>;
}
<div appParent>
Parent div directive
<div appChildAbc>
Abc Child directive 1
</div>
<div appChildAbc>
Abc Child directive 2
<div appChildXyz>
Xyz Child directive 1
</div>
<div appChildXyz>
Xyz Child directive 2
</div>
</div>
you can use @ContentChildren
decorator to query child directive
ParentDirective
@Directive({
selector: "[appParent]"
})
export class ParentDirective {
@ContentChildren(ChildXyzDirective,{descendants: true})
xyzChildren : QueryList<ChildXyzDirective>;
@ContentChildren(ChildAbcDirective,{descendants: true})
abcChildren : QueryList<ChildAbcDirective>;
ngAfterContentInit() {
this.abcChildren.forEach(e => {
e.elementRef.nativeElement.style.background = "red";
});
this.xyzChildren.forEach(e => {
console.log(e)
e.elementRef.nativeElement.style.background = "green";
});
}
}
ContentChildren Use to get the QueryList of elements or directives from the content DOM. Any time a child element is added, removed, or moved, the query list will be updated, and the changes observable of the query list will emit a new value.