在Angular 1.x中以下代码的工作原理是,我想点击并在一个ng重复内翻转一张卡
<div class="card" ng-repeat="let card of cards">
<div class="flipcard" ng-class="{'flipped':isflipped}" ng-click="isflipped = !isflipped">
</div>
</div>
然而在Angular 2中当点击时,它会翻转ngFor循环中的每一张"卡片"。。。如何将ngClass条件仅绑定到元素本身?
<div class="card" *ngFor="let card of cards">
<div class="flipcard" [ngClass]="{'flipped': isflipped }" (click)="isflipped = !isflipped;">
</div>
</div>
将其更改为:
<div class="card" *ngFor="let card of cards">
<div class="flipcard" [ngClass]="{'flipped': card.isflipped }" (click)="card.isflipped = !card.isflipped;">
</div>
</div>
为什么它能与AngularJS(1.x)一起工作
ng-repeat
为每个迭代元素创建一个新的作用域,因此在迭代元素作用域上设置isFlipped
属性(每个元素唯一):
ng重复
ngRepeat
指令为集合中的每个项实例化一个模板。每个模板实例都有自己的作用域,其中给定的循环变量设置为当前集合项,$index
设置为项索引或键。
为什么它不适用于Angular(2+)
Angular不再有作用域,所以当您设置isFlipped
属性时,它在当前组件上,而不是与迭代元素相关的任何内容。
如果card
元素是对象:
对于您的特定情况,似乎每张卡都是一个Object,所以您可以像@Harry Ninh建议的那样,向每个card
元素添加一个属性isFlipped
。请考虑在定义card
元素的类或接口中声明此属性,否则AOT编译可能会失败。
如果您不想在类/接口上添加上下文属性,请参阅;如果可以有不止一张翻转的卡片(…)";部分
如果只能有一张翻转的卡片:
如果你只能有一张翻转的卡片,你可以在你的组件中添加一个属性currentCard
,并将迭代的卡片与模板中的当前卡片进行比较:
组件:
export class MyComponent{
// (...)
currentCard:Card;
// (...)
}
模板:
<div class="card" *ngFor="let card of cards">
<div class="flipcard" [ngClass]="{'flipped': card===currentCard }" (click)="currentCard = card">
</div>
</div>
如果可以有多个翻转卡,并且card
元素不是对象或可以为空
在这种情况下,你需要保持每个项目的翻转/未翻转状态,比如使用布尔值数组或以card
值为键和布尔值的Object
组件:
export class MyComponent{
// (...)
cards: Card=[];
private flipped: boolean[];
flip(index:number){
this.flipped[index]=!this.flipped[index]
}
// (...)
}
模板:
<div class="card" *ngFor="let card of cards: let i= index">
<div class="flipcard" [ngClass]="{'flipped': flipped[i] }" (click)="flip(i)">
</div>
</div>