Angular 2 Click + ngClass, how to apply ONLY to SELF but not ALL elements inside ngFor

喜夏-厌秋 提交于 2019-11-29 11:22:53

Change it to:

<div class="card" *ngFor="let card of cards">
    <div class="flipcard"  [ngClass]="{'flipped': card.isflipped }" (click)="card.isflipped = !card.isflipped;">
    </div>
</div>

Why does it work with AngularJS (1.x) ?

ng-repeat create a new scope for each iterated element, so the isFlipped property is set on the iterated element scope (unique for each element):

ngRepeat

The ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item, and $index is set to the item index or key.

Why is it not working with Angular (2+) ?

Angular has no scope anymore, so when you set the isFlipped property, it is on the current component, not anything related to the iterated element.

If card elements are Objects :

For your particular case, it seems that every card is an Object, so you can just add a a property isFlipped to every card element like @Harry Ninh suggests it. Think to declare this property inside the class or interface that defines card elements otherwise AOT compilation might fail.

If you don't want to add a contextual property onto your class/interface, see the "If there can be more than one flipped card(...)" part.

If there can be only one flipped card :

If you can only have one single flipped card, you can add a property currentCard to your component and compare the iterated card to the current one inside your template :

component :

export class MyComponent{
    // (...)
    currentCard:Card;
    // (...)
}

template :

<div class="card" *ngFor="let card of cards">
    <div class="flipcard"  [ngClass]="{'flipped': card===currentCard }" (click)="currentCard = card">
    </div>
</div>

If there can be more than one flipped card and card elements are not objects or can be null.

Well in this case you need to maintain the state flipped/ not flipped of each item, like using an array of boolean or an Object with card value as key and boolean values

component :

export class MyComponent{

    // (...)

    cards: Card=[];
    private flipped: boolean[];

    flip(index:number){
      this.flipped[index]=!this.flipped[index]
    }

    // (...)

}

template :

<div class="card" *ngFor="let card of cards: let i= index">
    <div class="flipcard"  [ngClass]="{'flipped': flipped[i] }" (click)="flip(i)">
    </div>
</div>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!