Angular 2 Click + ngClass, как применить ТОЛЬКО к SELF, но не ко всем элементам внутри ngFor

В Angular 1.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... как связать условие ngClass только с самим элементом?

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

2 ответа

Решение

Измените это на:

<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

ngRepeat Директива создает шаблон один раз для каждого элемента из коллекции. Каждый экземпляр шаблона получает свою собственную область, где заданная переменная цикла установлена ​​на текущий элемент коллекции, и $index устанавливается на индекс предмета или ключ.

Почему он не работает с Angular (2+)?

Angular больше не имеет смысла, поэтому при установке isFlipped свойство, оно находится на текущем компоненте, а не что-либо связанное с повторяющимся элементом.

Если card элементы являются объектами:

В вашем конкретном случае кажется, что каждая карта является объектом, поэтому вы можете просто добавить свойство isFlipped каждому card элемент как @Harry Ninh предлагает это. Подумайте, чтобы объявить это свойство внутри класса или интерфейса, который определяет 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 значение в качестве ключевых и логических значений

составная часть:

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>
Другие вопросы по тегам