Tony
Tony

Reputation: 109

How to access element from nested child component

I am trying to access elements inside a child element from parent like the following example code:

@Component({
    selector: 'parent',
    template: `<child></child>`
})
export class Parent implements AfterContentInit, AfterViewInit {
    @ViewChildren('element') viewChildren: QueryList<ElementRef>
    @ContentChildren('element', {descendants: true}) contentChildren: QueryList<ElementRef>

    ngAfterContentInit() {
        console.log(this.contentChildren)
    }

    ngAfterViewInit() {
        console.log(this.viewChildren)
    }
}
@Component({
    selector: 'child',
    template: `
        <div #element>Div1</div>
        <div>Div2</div>
        <div #element>Div3</div>
    `
})
export class Child {}

My actual results are empty arrays, but i would expect an array with Div1 and Div3. What am i doing wrong?

UPDATE

My real problem is:
I have a component that knows when to append/remove a css class in some elements. This elements may be in its own component or its child, grandchild and so its on. In other words, what i am trying to accomplish is a angular way to do the following line:

let elements = document.querySelectorAll("div[element]")

Upvotes: 5

Views: 7626

Answers (2)

ABOS
ABOS

Reputation: 3823

You can try to put ViewChildren logic into child component and emit changes to parent component, if the code is under your control.

In child component,

@ViewChildren('element') 
set viewChildren( v: QueryList<ElementRef>){
  this.viewChildrenChanges.emit(v);
}

@Output() viewChildrenChanges = new EventEmitter();

In parent component template,

<app-child name="{{ name }}" (viewChildrenChanges)="show($event)"></app-child>

This is something I can think of based on your current description/requirement.

demo https://stackblitz.com/edit/angular-adbo1h?file=src%2Fapp%2Fapp.component.html

btw, I have removed duplicate #element on child divs as angular complains about that.

Upvotes: 0

Nimer Awad
Nimer Awad

Reputation: 4199

Let me explain @ViewChildren first; it means that you have a child component in the HTML template and you wanna reach it in the component.ts file. For instance:

<child #nested> </child>

So, you will be able now to reach this component selector is the ts file using nested element name; like this:

@ViewChildren(‘nested’) child: Child;

You can make the same declaration for the required elements in the child component, like this:

@ViewChildren(‘element1’) element1: ElementRef;

And now it will be defined in the child and you can reach it from childvariable:

this.child.element1

And so on.

BTW, I don’t know if you can use one ref for more than element. But that should work.

Upvotes: 1

Related Questions