You can make use of template reference variables when it comes to referencing to the DOM element on your template/component.html.
First, we use the #
character to declare the template reference variables for both buttons.
<ul class="list-group">
<li class="list-group-item" *ngFor="let post of posts; let i = index">
<p style="font-size:35px;"> {{ post.title }}
<button class="btn btn-success" (click)="onYes(i)" #buttonYes>Love it!</button>
<button class="btn btn-danger" (click) ="onNo(i)" #buttonNo>Don't love it!</button> <br>
</li>
</ul>
And on you component.ts, we use @ViewChildren
to access the list of reference variables within the ngFor
. We will also pass the index of the clicked button to the methods binded to the click events. This will allow the component logic to access the index which is clicked, thus using the index to provide the references for the index of the element within the QueryList
.
Do note that we have to use the .ToArray()
to return a copy of the result from QueryList as an array, so that we can access the each element within the QueryList via its index. For more details regarding the usage of QueryList, feel free to refer to the documentation.
import { Component, ViewChildren, ElementRef, QueryList } from '@angular/core';
.
.
posts = [{
title: 'AAA',
yes: 0,
no: 0
},{
title: 'BBB',
yes: 0,
no: 0
}, {
title: 'CCC',
yes: 0,
no: 0
}];
onYes(index: number){
this.posts[index].yes++;
this.onWhich(index);
}
onNo(index: number){
this.posts[index].no++;
this.onWhich(index);
}
onWhich(index: number){
const parentNode = this.buttonYes.toArray()[index].nativeElement.parentNode;
if (this.posts[index].yes > this.posts[index].no) {
parentNode.style.backgroundColor = 'blue';
} else if (this.posts[index].no > this.posts[index].yes) {
parentNode.style.backgroundColor = 'red';
} else{
parentNode.style.backgroundColor = 'white';
}
}
I have created a demo.
Alternatively, the better solution is to use ngClass
, whereby the classes .list-group-item-success
and .list-group-item-danger
are conditionally applied based on the number of yes and no votes for each post
.
<ul class="list-group">
<li class="list-group-item" *ngFor="let post of posts; let i = index">
<p [ngClass]="{
'list-group-item-success': post.yes > post.no,
'list-group-item-danger': post.yes < post.no}" style="font-size:35px;"> {{ post.title }}
<button class="btn btn-success" (click)="onYes(i)" #buttonYes>Love it!</button>
<button class="btn btn-danger" (click) ="onNo(i)" #buttonNo>Don't love it!</button>
</p>
</li>
</ul>
And on the component.css, we define the classes required.
.list-group-item-success {
background-color: blue;
}
.list-group-item-danger {
background-color: red;
}
DEMO.