Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set id using (#) dynamically in angular?

I am working on an angular 6 application which uses dynamic components. I am using @ViewChild('<id>', { read: ViewContainerRef }) <id>; in order to refer to the divs I would populate with dynamic components. The ViewContainerRef looks for a # tag with an id to identify which item it refers to in the template.

I have created an accordion within which I want to dynamically add a specific reusable component, which I have been doing throughout the rest of the application by the process mentioned above. However, since there are many tabs in an accordion I want to add a loop using *ngFor that would do the job for me, where I set the #id using a value specified in the loop. I implemented the following template:

<app-create-feature-modal></app-create-feature-modal>
<app-button description="{{ 'pages[knowledge_base][buttons][accordion_add]' | translate }}" class="btn btn-primary btn-md accordion-button" (callFunction)="add()"></app-button>
<div class="acc">
  <div *ngFor="let item of meta; let i = index">
    <button class="accordion" (click)="toggle(i)">{{item.name}}</button>
    <div class="{{'panel panel-'+ i}}">
      <div #{{item.value}}></div>   <!--here-->
    </div>
  </div>
</div>

However, on running the application, the id is not properly set and on inspecting the console I see that the reference to @ViewChild is undefined, and even within the html there are no id's defined, just plain divs.

I cannot use id="{{item.value}}" because the ViewContainerRef does not recognize it, which is why this solution would not work for me.

Is there any possible way I can achieve this?

like image 509
Muhammad Hamza Avatar asked Mar 17 '26 14:03

Muhammad Hamza


1 Answers

You would use [attr.id]="item.value".

<div [attr.id]="item.value"></div>

Update

The idea of give "id" to a tag if when we want to use plain javaScript and get the html element using

  const el=document.getElementById(..)

But in Angular we should avoid use it. In Angular we have the "template reference variable. A simple #element. When is under a *ngFor generally we have no problem to use the same. If we use in the own html the "scope" avoid problems, so, e.g.

<div *ngFor="let item of meta; let i = index">
  <button class="accordion" (click)="toggle(item)">
       {{item.name}}
  </button>
  <div #element>Hello</div>
</div>

//code
toggle(el:HTMLElement)
{
    el.classList.toggle("mystyle");
}

See that when use in .html we get the HTMLElement or, if the reference variable is a component, the own component.

When we get in code we use ViewChildren

@ViewChildren('element') elements!:QueryList<ElementRef>

And we neend't pass the "element", so we can use

toogle(index:number)
{
    const el=elements.find((_,i:number)=>i==index)
    if (el)
       el.nativeElement.classList.toggle("mystyle");
}

See that in this case we get the "ElementRef", so we need use el.nativeElement

a stackblitz with this ideas

like image 86
Cornchips007 Avatar answered Mar 20 '26 04:03

Cornchips007



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!