我尝试使用 @Input
属性的 Typescript 访问器来拦截从父级到子级的更改。我从 docs 稍微改变了这个例子.
我在父类的方法中设置了两个父类属性更改,期望子类的绑定(bind) Input
属性将随之更改。我发现当属性在父级中更改如下时,setter
只触发一次:
this.name="John"; //but this.name = this.name + "r" will work
虽然对于这个它总是有效:
this.age++; // or this.age = this.age + 1;
要修复第一个问题,我需要在输出中使用 EventEmitter 来“通知”父级(我已经尝试过,并且有效),但为什么第二个不需要它?有人可以解释两者之间的真正区别以及为什么它不适用于第一个(或者为什么它适用于第二个)。
父类: ...
name = 'Jane';
age = 10;
changeName(){
this.name= "John";
}
changeAge(){
this.age++;
}
父 View :
<my-name [name]="name"></my-name>
<button (click)="changeName()">Click me to change the name</button>
<my-age [age]="age"></my-age>
<button (click)="changeAge()">Click me to change the age</button>
Child1 类:
private _name = '';
@Input()
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
console.log(name);
}
get name(): string { return this._name; }
子 1 View :
My name is {{name}}.
Child2 类: 私有(private)_age = 0;
@Input()
set age(age: number) {
this._age = age || 0;
console.log(age);
}
get age(): number { return this._age; }
Child2 View
I am {{age}} years old
最佳答案
经过一些研究和反射(reflection),我发现/记得只有在检测到变化时才会更新绑定(bind)。
因此,如果 name
属性设置如下:
this.name= "John";
第一次运行改变了属性的初始值,因此访问器被触发。对于第二次和其他时间,相同的语句不会触发更改检测,因为值没有更改(它已经是“John”),因此访问器不会触发。
而对于 age
属性,它总是随着递增而变化:
this.age++;
因此更改检测和访问器始终被触发。
关于angular - 使用 getter 和 setter 拦截@Input 变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46133186/