Danny908 Danny908 - 1 month ago 10
TypeScript Question

Angular 2: Bind class just to selected element [ngClass]

I'm displaying arrows in a header table with icons from bootstrap, the problem is when i make click on a column all the columns get the icon class here is what talking about:
enter image description here

This is the code:

HTML ->

<table class="table table-hover">
<thead>
<th (click)="orderBy('username')">Username<span [ngClass]="displayArrow()"></span></th>
<th (click)="orderBy('email')">Email<span [ngClass]="displayArrow()"></span></th>
<th (click)="orderBy('id')">Id<span [ngClass]="displayArrow()"></span></th>
<th (click)="orderBy('roleId')">Role Id<span [ngClass]="displayArrow()"></span></th>
</thead>
<tbody>
<tr *ngFor="let user of usersListData | orderByController: OrderByParams">
<td (click)="onSelectFilterParam(user.username)">{{user.username}}</td>
<td (click)="onSelectFilterParam(user.email)">{{user.email}}</td>
<td (click)="onSelectFilterParam(user.id)">{{user.id}}</td>
<td (click)="onSelectFilterParam(user.roleId)">{{user.roleId}}</td>
</tr>
</tbody>




AppComponent ->

private toggleArrow = 0;

orderBy(columnName: string) {
this.toggleArrow++;
if(this.toggleArrow > 2) {
this.toggleArrow = 0;
}
console.log(this.toggleArrow);
}

displayArrow() {
if(this.toggleArrow === 0) {
return '';
}
else if(this.toggleArrow === 1) {
return 'glyphicon glyphicon-chevron-up';
}
else if(this.toggleArrow === 2) {
return 'glyphicon glyphicon-chevron-down';
}
}


It's possible just bind the class to one element?

Answer

This might not be the most elegant of solutions, but you can do something like this by declaring the columns in your component.

   columns: any[] = [
      {'Name':'username','Direction':0},
      {'Name':'email','Direction':0},
      {'Name':'id','Direction':0},
      {'Name':'roleId','Direction':0}
    ]

In your HTML you could do something like this:

<table class="table table-hover">
<thead>
    <th *ngFor="let col of columns" (click)="orderBy(col.Direction)">{{ col.Name }}<span [ngClass]="displayArrow(col.Direction)"></span></th>
</thead>
<tbody>
    <tr *ngFor="let user of usersListData | orderByController: OrderByParams">
        <td (click)="onSelectFilterParam(user.username)">{{user.username}}</td>
        <td (click)="onSelectFilterParam(user.email)">{{user.email}}</td>
        <td (click)="onSelectFilterParam(user.id)">{{user.id}}</td>
        <td (click)="onSelectFilterParam(user.roleId)">{{user.roleId}}</td>
    </tr>
</tbody>

OrderBy would then be

orderBy(dir: number) {
    dir++;
    if(dir > 2) {
        dir = 0;
    }
    console.log(dir);
}

and finally the displayClass()

displayArrow(dir: number): string {
    if(dir === 0) {
        return '';
    }
    else if(dir === 1) {
        return 'glyphicon glyphicon-chevron-up';
    }
    else if(dir === 2) {
        return 'glyphicon glyphicon-chevron-down';
    }
}