10

I have a code block angular 2 like that:

<div *ngFor="let elm of elms; let i = index" [attr.name]="name" text-center>
    {{elm }}
</div>

It works fine.
But when i want to dynamic set attribute name base on index like name-1="name" name-2="name"i dont know how to do it.
I tried [attr.name-{{i}}]="name"or [attr.name- + i]="name" but it does not work. Is there any way to do it?
Many thanks.

8
  • how does the resulting html look like? <div name1="name"...? Commented Jun 16, 2017 at 7:26
  • @Maximus, <div name-1="name"... <div name-2="name"... Commented Jun 16, 2017 at 7:31
  • @VladimirZdenek, Sorry, it does not work Commented Jun 16, 2017 at 7:36
  • Can you please be more specific of what you want to achieve ? Commented Jun 16, 2017 at 7:43
  • Certainly you can create an attribute directive for this. Commented Jun 16, 2017 at 7:47

2 Answers 2

8

To start off thanks to OP for the question. I eventually learnt new things by solving this answer. Below explanation on how i achieved.


Important: One catch you cannot bind the dynamic attribute to your component scope. To achieve this you need to make each div as a dynamic component and compile it. Kinda hacky i guess.


Template:

<div #looped *ngFor="let elm of elms; let i = index;" text-center>
  {{elm }}
</div>

and in the component import implements AfterViewInit and ViewChildren decorator to get children elements and its changes on rendering:

import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';

component:

export class ExamplePage implements AfterViewInit {
  elms : Array<string> = ["d1", "d2", "d3"]
  @ViewChildren('looped') things: QueryList<any>;
  constructor() { }

  ngAfterViewInit() {
    this.things.forEach((t, index) => {
      let el : HTMLDivElement = t.nativeElement;
      el.setAttribute("name-" + index , "dynamicAttrString");
    })
  }
}

Output:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

wow. It is cool. i will check it soon and acept your answer. Thanks
It works. I accepted it. But there are some points i don't understand. 1. Why need to implement AfterViewInit? 2. If place code in ngAfterViewInit, it only work when the data is ready in start time. To apply code in anychange, i use ngAfterViewChecked instead. But there is a problem that ngAfterViewChecked fire so many time in one change and it will make my app slower. What i should to do? Thank you
@Duannx in that case separate the logic in the form of a function and call on ngChange of that particular model.
3

I don't know weather it is possible or not but I've alternate solution

<div *ngFor="let elm of elms; let i = index" [attr.name]="{id : index, data : name}">{{item}}</div>

then you'll get object as avalue with id and data keys, hope this helps.

1 Comment

It is just a walk around. I just want to know have or not anyway to solve the main problem. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.