我可以想到一些方法可以解决这个问题,但我想对大多数' Angular' 的做法提出一些建议。
我把an example of what I'm doing放在一起。
主要组件使用NgFor
迭代列表并创建一堆子组件。
每个子组件在单击时发出一个由父组件拾取的事件。每个孩子也有一个方法update()
。
我想要的是我的主要组件获取对任何一个孩子发出事件并引用其update()
方法的引用的正确方法。
看起来非常简单(可能非常简单),但它是我构建的应用程序的一个核心功能,所以我希望尽可能干净整洁。
为你提供帮助
答案 0 :(得分:4)
最简单的方法是使用模板变量来引用子组件:
<my-child #child *ngFor="let row of rowList;" [id]="row.name"
(onMD)="processClick($event); child.update()"></my-child>
答案 1 :(得分:3)
由于Angular 2采用了单向数据流范例,我认为解决这个问题的“最”Angular'方式是不调用update()
方法所有。子组件的状态应由父组件提供。
每当点击发生时,应在App
(父)组件中计算新状态,并将其传递给ChildComponent
。
这样,您需要通过附加属性(例如clicked
)扩展父级中保存的状态:
rowList = [{name: "Alice", clicked: false}, ...];
(当然,由于undefined
与false
具有相同的逻辑值,因此不需要显式声明。)
单击,在处理程序方法中,计算新状态。在这种情况下,它只是一个简单的布尔值更改:
processClick(id){
this.recentClick = id;
// Create the new array for immutability benefits.
this.rowList = this.rowList.map(person => {
if (person.name === id) {
return {name: person.name, clicked: true};
} else {
return person;
}
})
}
与任何其他@Input
一样,该值会传递给孩子。
<my-child *ngFor="let row of rowList;" [id]=row.name [clicked]=row.clicked (onMD)="processClick($event)"></my-child>
现在,子组件可以根据clicked
属性的值更改其行为。作为奖励,当使用不可变数据时,您可以将更改检测策略更改为some performance benefits的onPush
。
@Component({
// ...
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
@Input() clicked: boolean;
get prefix() {
return this.clicked ? "Bye!" : "Hi";
}
// ...
}
这种方法有很多好处。
update()
行为有效的代码。完整实施如下所示:http://plnkr.co/edit/IP8iLKxKGCjHOdgPHJ0h?p=preview