我有两个相互通信的组件,一个常规组件(父组件)和一个引导模式组件(子组件)。 父母和孩子都有一个带有记录的表。在父母的表中,每个记录都有一个复选框。当我选中一个或多个复选框并单击一个按钮时,会触发一个事件,尝试填充该孩子的桌子。
填充了孩子的桌子,我可以从中删除我希望的记录。如果删除某些记录,关闭模式(关闭子级)并决定再次将相同的数据从父级发送到子级,则不会触发Input
事件。但是,如果我选择检查父项中的不同记录并将它们传递给子项,则Input
事件将被正确触发。
这就是我所拥有的:
ParentComponent.component.html
<child-component #createNewProductRequestModal [data]="newProductRequest"></m-child-component>
ParentComponent.component.ts
private onNewProductRequest(toSend){
this.newProductRequest = toSend;
$('#createNewProductRequestModal').appendTo("body").modal('toggle');
}
ChildComponent.component.ts
@Input('data')
set data(data: any) {
if (data !== undefined || data !== "") {
this.products = data;
console.log("data");
}
}
constructor() { }
ngOnInit() { }
要测试在渲染子表之前是否更改了数据,我记录了父级传递到控制台的数据。使用此代码,每次我执行父级的onNewProductRequest(toSend)
而不更改toSend
变量时,子级的模态渲染都会执行,但不会执行Input
事件,因此不会更改数据。
答案 0 :(得分:1)
您可以使用ngOnChanges
angular docs的定义
一种回调方法,如果更改了默认值,则该方法将在默认更改检测器检查了数据绑定属性之后,并且在检查视图和内容子级之前立即调用。
您在子元素上有一些输入
@Input() nameOfInput: any;
您的子组件必须实现OnChanges
,如下所示:
export class ChildComponent implements OnChanges {
然后在下一步中,您需要对输入的每次更改进行操作。
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
if ('nameOfInput' in changes) {
console.log('Old value: ', changes.nameOfInput.previousValue);
console.log('New value: ', changes.nameOfInput.currentValue);
}
}
看这个例子。
答案 1 :(得分:1)
将数据分配给输入时,由于对象发生更改,因此第一次检测到更改,但是如果您更改了对象内部的属性,则引用和对象仍然相同,因此不会触发更改。解决方案是克隆您通过输入发送给子对象的对象。尝试更改此行:
this.newProductRequest = toSend;
为此:
this.newProductRequest = {...toSend};
答案 2 :(得分:1)
第二次将相同的数据发送到子组件时,Angular不会将其注册为对@Input()的更改,因为您传递的是与第一次传递的对象引用相同的对象,而Angular是只是比较参考。
尝试这个小小的改变:
private onNewProductRequest(toSend){
this.newProductRequest = { ...toSend };
$('#createNewProductRequestModal').appendTo("body").modal('toggle');
}
这将意味着您将数据对象的浅表副本传递给子对象,而不只是原始对象的修改版本。由于此浅表副本将对原始对象有不同的引用,因此Angular会将其作为更改并触发您的@Input setter。
答案 3 :(得分:0)
尝试
在子组件中
import {Component, OnChanges, SimpleChanges, Input} from '@angular/core';
ngOnChanges(changes: SimpleChanges) {
for (let propName in changes) {
let change = changes[propName];
let curVal = JSON.stringify(change.currentValue);
let prevVal = JSON.stringify(change.previousValue);
console.log(curVal);
console.log(prevVal);
}
}