angular - 使用 getter 和 setter 拦截@Input 变化

标签 angular typescript angular2-template

我尝试使用 @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 来“通知”父级(我已经尝试过,并且有效),但为什么第二个不需要它?有人可以解释两者之间的真正区别以及为什么它不适用于第一个(或者为什么它适用于第二个)。

DEMO


父类: ...

  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/

相关文章:

javascript - 如何检查变量是否不是假值但 0 在 Javascript 中传递

Angular 2 : Display different "toolbar" components depending on main navigation

angular - 将Angular 5更新为Angular 6错误

javascript - 如何模拟用户对输入和按钮元素的交互?

angular - RxJS Observable with Subject,通过计时器轮询和 combineLatest 不会触发

angular - 构建 Angular 代码源以贡献时出错

javascript - 时间计数器 - typescript

typescript - 字符串类型转数字

typescript - angular2 – 通过自定义管道使用全局服务

angular - 如何使用 ngForTemplate 包装模板?