【问题标题】:Angular5 property binding arrays with @Input带有 @Input 的 Angular 属性绑定数组
【发布时间】:2018-09-29 17:22:25
【问题描述】:

我正在尝试通过 EventEmitter 将组件的更改通过其父级传播到其兄弟姐妹之一。改变的是数组中用户的状态。

这是我的代码:

child1.component.ts(来源)

@Output() adminAdded = new EventEmitter<Array<AdminDetails>>();
...
setAdminStatus(index: number, status: string): void {
  this.admins[index].status = status;
  this.adminAdded.emit(this.admins);
}

parent.component.ts

onAdminAdded(adminDetails: Array<AdminDetails>): void {
  Object.assign(this.adminDetails, adminDetails]);
}

parent.component.html

<child1-component (adminAdded)="onAdminAdded($event)"></child1-component>
<child2-component [admins]="adminDetails"></child2-component>

child2.component.ts

adminMails: string[];
@Input() set admins(admins: Array<AdminDetails>) {
    if (!admins) {
        return;
    }
    adminMails = admins.filter(x => x.status === 'Active').map(x => x.email);
}

我在这里显示活跃管理员的电子邮件。问题是更改只到达父组件。 Object.assign 处的断点被命中,但在 setter 中却没有。

我认为这是因为对数组的引用是相同的,并且它无法识别更改。有什么想法吗?

【问题讨论】:

    标签: arrays angular data-binding


    【解决方案1】:

    你是对的,Angular 只在引用对象发生变化时检测到变化,而不是在其内容发生变化时检测到变化。

    您可以通过将逻辑移动到 DoCheck 生命周期挂钩中来绕过此问题,该挂钩能够检测对象属性的变化。

    编辑

    如前所述,如果您担心 DoCheck 被过于频繁地调用,创建一个全新的对象并将其重新分配给您的输入属性应该可以解决问题,因为引用会有所不同。

    【讨论】:

    • 我读到了 DoCheck 钩子,但它似乎经常被称为真实的。有没有办法强制更新输入属性?
    • 如果您担心 DoCheck 被频繁调用,创建一个全新的对象并将其重新分配给您的输入属性应该可以解决问题,因为引用会有所不同。
    • @bugs 你能把它编辑成答案,这样我可以接受吗?
    • @AnandG 谢谢,但我不想引入一个全新的服务和使用 observable 来跟踪数组的开销。
    • 编辑了答案
    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 2018-11-29
    • 1970-01-01
    • 2018-01-11
    • 2017-02-15
    • 1970-01-01
    • 2018-11-20
    • 2020-03-22
    相关资源
    最近更新 更多