Angular 2 Click + ngClass,如何只应用于 SELF 而不是 ngFor 中的所有元素
Angular 2 Click + ngClass, how to apply ONLY to SELF but not ALL elements inside ngFor
在Angular1.x
以下代码可以正常工作,因为我想在 ng-repeat
中单击并翻转卡片
<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 循环内每隔 "card" 翻转一次...如何将 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
属性 设置在迭代元素范围(每个元素唯一):
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.
为什么它不适用于 Angular (2+)?
Angular 不再有范围,所以当您设置 isFlipped
属性 时,它在当前组件上,与迭代元素无关。
如果 card
个元素是对象:
对于您的特定情况,似乎每张卡片都是一个对象,因此您可以像@Harry Ninh 建议的那样向每个 card
元素添加一个 属性 isFlipped
。 考虑在定义 card
元素的 class 或接口中声明此 属性 否则 AOT 编译可能会失败。
如果您不想在 class/interface 上添加上下文 属性,请参阅“如果可以有多个翻转的卡片(...)”部分。
如果只有一张翻转的牌:
如果你只能有一张翻转的卡片,你可以在你的组件中添加一个 属性 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
个元素不是对象或者可以为null。
在这种情况下,您需要保持每个项目的翻转/未翻转状态,例如使用布尔数组或以 card
值为键和布尔值的对象
分量:
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>
在Angular1.x 以下代码可以正常工作,因为我想在 ng-repeat
中单击并翻转卡片<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 循环内每隔 "card" 翻转一次...如何将 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
属性 设置在迭代元素范围(每个元素唯一):
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.
为什么它不适用于 Angular (2+)?
Angular 不再有范围,所以当您设置 isFlipped
属性 时,它在当前组件上,与迭代元素无关。
如果 card
个元素是对象:
对于您的特定情况,似乎每张卡片都是一个对象,因此您可以像@Harry Ninh 建议的那样向每个 card
元素添加一个 属性 isFlipped
。 考虑在定义 card
元素的 class 或接口中声明此 属性 否则 AOT 编译可能会失败。
如果您不想在 class/interface 上添加上下文 属性,请参阅“如果可以有多个翻转的卡片(...)”部分。
如果只有一张翻转的牌:
如果你只能有一张翻转的卡片,你可以在你的组件中添加一个 属性 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
个元素不是对象或者可以为null。
在这种情况下,您需要保持每个项目的翻转/未翻转状态,例如使用布尔数组或以 card
值为键和布尔值的对象
分量:
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>