Angular2:如果值未更改,输入 setter 不会拾取设置事件
Angular2: Input setter not picking up set event if value does not change
在这里参考 Angular2 文档文件:[https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter](父到子 setter),我有以下子组件代码:
import { Component, Input } from '@angular/core';
@Component({
selector: 'name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
private _name = '';
@Input()
set name(name: string) {
console.log("name change");
this._name = name;
}
get name(): string { return this._name; }
}
父类很简单:
import { Component } from '@angular/core';
@Component({
selector: 'name-parent',
template: `
<h2>Parent </h2>
<name-child [name]="name"></name-child>
`
})
export class NameParentComponent {
// somewhere on ngOnInit, set name without changing value
ngOnInit() {
// get pending paged only and so on
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
},1000);
},1000);
},1000);
}
}
您希望控制台在 3 秒内注销 "name change" 三次。它不会,它只记录一次,并忽略后续集(仅当值未更改时才会发生这种情况)。无论值是否更改,如何让输入获取设置事件?
我看到有两种解决方法:
1) 使用不可变值
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
}, 1000);
}, 1000);
}, 1000);
2) 直接改变输入属性
@ViewChild(NameChildComponent) child: NameChildComponent;
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
}, 1000);
}, 1000);
}, 1000);
你给的文章明确说
Intercept input property changes with a setter
当您想要实现的目标根本不是跟踪 更改 时。它是关于 从 parent 向 child 发送一个事件 并且这是 RX Subject
(其中 4 个中的任何一个)或 Angular2 EventEmitter
真的很不错
您可以在 parent 中创建其中之一并将其传递给 child。然后,订阅之后,你可以跟踪所有的事件,不管值是多少。
如果使用输入 setter 是严格要求,则不是肯定的,但您是否尝试过使用 OnChanges?
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent implements OnChanges {
@Input() name;
ngOnChanges(changes: SimpleChanges) {
if (changes['name']) {
console.log(`Is First Change: ${changes['name'].isFirstChange}`)
console.log(`name change from ${changes['name'].previousValue} to ${changes['name'].currentValue}`);
}
}
}
虽然 yurzui 的回答已经足够解释了,但如果它是一个对象,你可以使用
let newObj = JSON.parse(JSON.stringify(oldObj))
它将触发 setter 事件
在这里参考 Angular2 文档文件:[https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter](父到子 setter),我有以下子组件代码:
import { Component, Input } from '@angular/core';
@Component({
selector: 'name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
private _name = '';
@Input()
set name(name: string) {
console.log("name change");
this._name = name;
}
get name(): string { return this._name; }
}
父类很简单:
import { Component } from '@angular/core';
@Component({
selector: 'name-parent',
template: `
<h2>Parent </h2>
<name-child [name]="name"></name-child>
`
})
export class NameParentComponent {
// somewhere on ngOnInit, set name without changing value
ngOnInit() {
// get pending paged only and so on
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
setTimeout(() => {
this.name = "a";
},1000);
},1000);
},1000);
}
}
您希望控制台在 3 秒内注销 "name change" 三次。它不会,它只记录一次,并忽略后续集(仅当值未更改时才会发生这种情况)。无论值是否更改,如何让输入获取设置事件?
我看到有两种解决方法:
1) 使用不可变值
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
setTimeout(() => {
this.name = new String("a");
}, 1000);
}, 1000);
}, 1000);
2) 直接改变输入属性
@ViewChild(NameChildComponent) child: NameChildComponent;
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
setTimeout(() => {
this.child.name = "a";
}, 1000);
}, 1000);
}, 1000);
你给的文章明确说
Intercept input property changes with a setter
当您想要实现的目标根本不是跟踪 更改 时。它是关于 从 parent 向 child 发送一个事件 并且这是 RX Subject
(其中 4 个中的任何一个)或 Angular2 EventEmitter
真的很不错
您可以在 parent 中创建其中之一并将其传递给 child。然后,订阅之后,你可以跟踪所有的事件,不管值是多少。
如果使用输入 setter 是严格要求,则不是肯定的,但您是否尝试过使用 OnChanges?
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent implements OnChanges {
@Input() name;
ngOnChanges(changes: SimpleChanges) {
if (changes['name']) {
console.log(`Is First Change: ${changes['name'].isFirstChange}`)
console.log(`name change from ${changes['name'].previousValue} to ${changes['name'].currentValue}`);
}
}
}
虽然 yurzui 的回答已经足够解释了,但如果它是一个对象,你可以使用
let newObj = JSON.parse(JSON.stringify(oldObj))
它将触发 setter 事件