6
votes

I have the following DOM structure

<div #carousalElement>
    <div  class="singleCaousalElement">
        <a>
            <img [src]="carousalURL1" class="carousalImage">
        </a>
    </div>
    <div  class="singleCaousalElement">
        <a>
            <img [src]="carousalURL2" class="carousalImage">
        </a>
    </div>
</div>

I can get the all divs with carousalElements class using the ViewChildren

@ViewChildren('carousalElement') carousalElements;

PROBLEM: When I dynamically add a new div under the #carousalElement div, it does not show up under the carousalElements array.

Am I missing something obvious?

4
How do you add new div? - yurzui
Using this.carousalContainer.nativeElement.insertAdjacentHTML('afterbegin', 'newDivText'); - Giridhar Karnik
What is the carousalContainer? - yurzui
Anyway it won't work because you need to use *ngFor if you want carousalElements gets updated - yurzui

4 Answers

6
votes

Angular doesn't recognize HTML not added by Angular directives or APIs. Also if the <div> doesn't have a template variable #carousalElement, @ViewChildren('carousalElement') won't find it.

Template variables need to be added statically in the components template. Adding them dynamically is meaningless. Angular processes Angular-specific template constructs only during compilation of a template.

0
votes

At point when you add new element in your carousalElement div at that time check in DOM if that element is available or not.

If available get element by:

this.carousalElements.NativeElement......

If not available then try to set some timeout then after check again in DOM

setTimeout(() => {
        //your logic
    }, 200);

Still not find then try with below logic:

@ViewChildren('carousalElement', { read: ViewContainerRef })
public carousalElement: QueryList<ViewContainerRef>;

And where you check console.log(this.carousalElement)

Let me know what it gives

0
votes

In JavaScript there are two data types: primitive and object.

In Angular there are basically 3 data types (glossing over plenty here): primitive, object, and reactive. Without going into details

@ViewChildren('carousalElement') carousalElements;

Is of the data type reactive. In Angular, this means there is an observer in this case the amount of elements with the caoursalElement templateVariable, your variable carousalElements is an advanced form of subscription to @ViewChildren, which is an observer to access the updated array you simply need

()=>{return this.carousalElements}

Make sure your HTML template is using your template vars correctly and this should work

0
votes

You can add the service ChangeDetectorRef and call the method this.changeDetectorRef.detectChanges() when you add another child with the ref that you have referenced in ViewChildren QueryList. That worked for me!