Reputation: 47
I need to assign a class to a div that is inside a *ngFor iteration, based on a method.
Below is my HTML code: -
<ng-container *ngFor="let data of totalData let j = index">
<div>
<a (click)="selectData(data)">
<div [ngClass]="{selected : selectedCodeMethod(data)}">
{{data.code}}
</div>
</a>
</div>
</ng-container>
My Ts code:-
selectedCodeMethod(data){
if(this.selectedCode.includes(data.code)){
return true;
}
return false;
}
selectData(data){
this.selectedCode.push(data.code);
}
Even if the selectedCodeMethod() changes the content of selectedCode array, the method inside ngClass doesn't reflect changes.
What changes do I need to make?
Upvotes: 0
Views: 684
Reputation: 1138
Calling function in Angular template is discouraged since it is inefficient and can raise errors - more about it in this article.
Back to your question, you should create Angular Pipe
to match your needs. In your scenario we need a pipe that accepts an array
and an element
and return array.includes(element);
:
@Pipe({
name: "includes"
})
export class IncludesPipe implements PipeTransform {
transform<T>(array: T[], element: T): boolean {
return array.includes(element);
}
}
Next, in your component you need to use the pipe and pass additional arguments
@Component({
selector: "app-root",
template: `
<ul>
<li
*ngFor="let item of items"
[ngClass]="{ selected: selectedItems | includes: item }"
>
Item {{ item }}
</li>
</ul>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent {
items = [1, 2, 3, 4, 5];
selectedItems = [1, 3];
}
Lastly, pipes are pure, meaning you need to make immutable updates:
selectData(data){
this.selectedCode = [ ...this.selectedCode, data.code ];
}
You can experiment with the code in this Code Sandbox
Upvotes: 1