У меня есть коллекция карточных предметов
...
cards: Card[];
...
ngOnInit() {
this.cardService.getCards.subscribe(r => { this.cards = r; });
}
Я добавляю компоненты дочерней карты в шаблон, как это
<div id="cards-container">
<app-card *ngFor="let card of cards" [name]="card.name"></app-card>
</div>
Компонент Card имеет имя и стиль, зависящий от активного атрибута, который переключается при нажатии на компонент
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
'styleUrls: ['./card.component.scss']
})
export class CardComponent {
private _name = '';
private _active = false;
// getters/setters
...
onClick(e) {
this.active = !this.active;
}
}
card.component.html
<div [ngClass]="{'card': true, 'active': _active}"
(click)="onClick($event)">
{{name}}
</div>
Все это прекрасно работает.
Проблема:
В родительском компоненте мне нужно перебрать все компоненты карты, которые были добавлены с помощью *ngFor="let card of cards"
, и установить их все активными или не активными, но я не могу понять, как это сделать.
Что я пробовал:
Я пытался использовать @ViewChildren()
, но метод QueryList toArray()
всегда дает мне пустой массив. Из ограниченных примеров в документации ViewChildren Я не уверен на 100%, нужна ли мне дополнительная Директива в родительском компоненте или директивы в примерах просто используются для демонстрации. Так что я попробовал
@ViewChildren(CardComponent) cardList: QueryList<CardComponent>;
Я также пытался использовать ViewContainerRef , используя что-то похожее на этот ответ , но мне не удалось заставить его работать, и кажется, что это не ведет меня в правильном направлении. Я также просмотрел документацию для ComponentRef , но не понимаю, как или если это может помочь мне решить мою проблему.
Любые предложения указать мне правильное направление приветствуются.
UPDATE
Мой активный установщик в компоненте карты выглядит так
@Input()
set active(active: boolean) {
this._active = active;
}
Мне нужно иметь возможность изменить это для всех карт в любой момент, другими словами, опция «выбрать / отменить выбор всех».
РЕШИТЬ!
Принимая предложение от @Tim Klein , я подписался на changes
из QueryList и смог получить мои компоненты в массиве, который я обновляю при изменении QueryList. Теперь я просто перебираю массив компонентов и вызываю мой active
setter.
cards: CardComponent[];
@ViewChildren(CardComponent) cardList: QueryList<CardComponent>;
...
ngAfterViewInit(): void {
this.cards = this.cardList.toArray(); // empty array but that's okay
this.cardList.changes.subscribe((r) => {
this.cards = this.cardList.toArray(); // we get all the cards as soon as they're available
});
}