简体   繁体   English

使用getter和setter拦截@Input的变化

[英]Intercepting @Input changes with getter and setter

I tried to use Typescript accessors for @ Input property to intercept changes from the parent to the child. 我尝试使用@ Input属性的Typescript访问器来拦截从父级到子级的更改。 I changed a little bit this example from the docs . 我从文档中改变了一些这个例子。

I set two parent properties change in parent's methods expecting that child's binded Input properties will follow. 我在父方法中设置了两个父属性更改,期望子项的绑定Input属性将遵循。 I found that when the property is changed in the parent as the following, the setter fires only once: 我发现当在父项中更改属性时, setter只触发一次:

  this.name="John"; //but this.name = this.name + "r" will work

while for this one it works always: 而对于这一个,它始终有效:

  this.age++; // or  this.age = this.age + 1;

To fix the first one I need to 'notify' the parent with an EventEmitter in an Output (which I already tried, and it works), but why the second one doesn't need it? 要解决第一个问题,我需要在输出中使用EventEmitter“通知”父级(我已经尝试了,它可以工作),但是为什么第二个不需要呢? Could someone explain the real differences between the two and why it doesn't work for the first one (or why it works for the second one). 有人可以解释两者之间的真正差异,以及为什么它不适用于第一个(或者为什么它适用于第二个)。

DEMO DEMO


Parent class: ... 家长班: ......

  name = 'Jane';
  age = 10;

  changeName(){
    this.name= "John";
  }

  changeAge(){
    this.age++;
  }

Parent 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 Class: 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; }

Child1 view: Child1查看:

  My name is {{name}}.

Child2 class: private _age = 0; Child2类: private _age = 0;

 @Input()
  set age(age: number) {
    this._age = age || 0;
    console.log(age);
  }

  get age(): number { return this._age; }

Child2 view Child2视图

  I am {{age}} years old

After some research and reflexion, I found/remembered that bindings are only updated when there is a change detection. 经过一些研究和反思,我发现/记得只有在有变化检测时才会更新绑定。 So in case name property is set as following: 因此,如果name属性设置如下:

this.name= "John";

the first run changes the initial value of the property, so the accessor is fired. 第一次运行会更改属性的初始值,因此会触发访问者。 For the second and other times, the same statement will not trigger the change detection as the value didn't change (it was already "John") and consequently the accessor will not fire. 对于第二次和其他时间,相同的语句将不会触发更改检测,因为值没有更改(它已经是“John”),因此访问器将不会触发。
While for the age property, it's always a value change as it increments: 对于age属性而言,它随着价值的增加而变化:

this.age++;

so the change detection and accessor are always fired. 所以变更检测和访问器总是被触发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM