以编程方式设置动态添加的子组件的属性
Programmatically set attribute of dynamically added child component
我收集了卡片对象
...
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()
but the QueryList's toArray()
method always gives me an empty array. From the limited examples in the ViewChildren documentation 我不是 100% 清楚我是否需要在父组件中添加一个额外的指令,或者示例中的指令是否仅用于演示。所以我尝试的是
@ViewChildren(CardComponent) cardList: QueryList<CardComponent>;
我也尝试过使用 ViewContainerRef using something similar to this answer but I was unable to make it work and it seems like that is not taking me in the right direction. I also looked at the documentation for ComponentRef,但我不知道这如何或是否可以帮助我解决我的问题。
任何能为我指明正确方向的建议都将不胜感激。
更新
我在卡片组件中的活动setter是这样的
@Input()
set active(active: boolean) {
this._active = active;
}
我需要能够随时更改所有卡片的此项,换句话说,"select/deselect all" 选项。
已解决!
采用 ,我订阅了 QueryList 的 changes
,并且能够在一个数组中获取我的组件,我在 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
});
}
我认为您可能面临的问题是,一旦调用了 afterViewInit
生命周期事件,您的动态组件仍然没有加载。因此,如果您在 afterViewInit
内部调用 cardList.toArray()
,它将 return 一个空列表,因为您的组件尚未添加到父组件的视图中。
您应该尝试订阅 changes
可观察对象(如 this example)并在回调中调用您的逻辑来更改子组件的状态。
更新
另一种选择是简单地为您的子组件提供另一个输入,该输入可以接受布尔值作为其活动状态。
然后,当您设置 Card
个对象的列表时,只需遍历并更改一些 active
属性。只需在父组件的模板中设置 属性 和 name
。
我收集了卡片对象
...
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()
but the QueryList's toArray()
method always gives me an empty array. From the limited examples in the ViewChildren documentation 我不是 100% 清楚我是否需要在父组件中添加一个额外的指令,或者示例中的指令是否仅用于演示。所以我尝试的是
@ViewChildren(CardComponent) cardList: QueryList<CardComponent>;
我也尝试过使用 ViewContainerRef using something similar to this answer but I was unable to make it work and it seems like that is not taking me in the right direction. I also looked at the documentation for ComponentRef,但我不知道这如何或是否可以帮助我解决我的问题。
任何能为我指明正确方向的建议都将不胜感激。
更新
我在卡片组件中的活动setter是这样的
@Input()
set active(active: boolean) {
this._active = active;
}
我需要能够随时更改所有卡片的此项,换句话说,"select/deselect all" 选项。
已解决!
采用 changes
,并且能够在一个数组中获取我的组件,我在 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
});
}
我认为您可能面临的问题是,一旦调用了 afterViewInit
生命周期事件,您的动态组件仍然没有加载。因此,如果您在 afterViewInit
内部调用 cardList.toArray()
,它将 return 一个空列表,因为您的组件尚未添加到父组件的视图中。
您应该尝试订阅 changes
可观察对象(如 this example)并在回调中调用您的逻辑来更改子组件的状态。
更新
另一种选择是简单地为您的子组件提供另一个输入,该输入可以接受布尔值作为其活动状态。
然后,当您设置 Card
个对象的列表时,只需遍历并更改一些 active
属性。只需在父组件的模板中设置 属性 和 name
。