【问题标题】:Listen to Changes on an Object's field in Angular2/Typescript在 Angular2/Typescript 中监听对象字段的变化
【发布时间】:2017-10-03 07:36:59
【问题描述】:

在 Angular2/Typescript 中,是否可以“观察”对象的字段以进行更改。

例如,假设我有一个类 Person,其中包含字段 firstName、lastName 和 fullName。是否可以在 firstName 或 lastName 更改时自动更新 fullName?

类似这样的:

export class Person {
  firstName: string= '';
  lastName: string = '';
  fullName: string = '';

  constructor(firstName: string, lastName: string) {
    this.firstName.onChange(() => { this.updateFullName(); });
    this.lastName.onChange(() => { this.updateFullName(); });

    this.firstName = firstName;
    this.lastName = lastName;
  }

  updateFullName() {
    this.fullName = `${this.firstName} ${this.lastName}`;
  }
}

【问题讨论】:

    标签: typescript angular observable


    【解决方案1】:

    第一种方法

    您可以利用如下所述的 TypeScript setter / getter 来同步 fullName 与 firstName 和 lastName:

    get lastName() {
      return this._lastName;
    }
    
    set lastName(lastName:string) {
      this._lastName = lastName;
      this.fullName = this._firstName + ' ' + this._lastName;
    }
    
    get firstName() {
      return this._firstName;
    }
    
    set firstName(firstName:string) {
      this._firstName = firstName;
      this.fullName = this._firstName + ' ' + this._lastName;
    }
    

    这样设置lastName或firstName时,fullName会自动更新:

    var p = new Person();
    p.lastName = 'last';
    p.firstName = 'first';
    console.log(p.fullName); // print 'first last'
    

    第二种方法

    默认情况下,Angular2 不允许定义对象内的属性更改。它只检测 at 引用的更新。我的意思是如果绑定属性的引用(或原始类型的值)被更新。

    也就是说,Angular2 允许使用 ngDoCheck 挂钩方法插入您自己的策略。

    您可以在其中利用 KeyValueDiffers 类(将被注入)来检测特定对象中的更新。

    查看此链接了解更多详情:

    这是一个示例:

    @Component({
      selector: 'my-component',
      (...)
    }) 
    export class MyComponent implements DoCheck {
      @Input() person: Person;
      differ: any;
    
      constructor(differs:  KeyValueDiffers) {
        this.differ = differs.find([]).create(null);
      }
    
      ngDoCheck() {
        var changes = this.differ.diff(this.person);
    
        if (changes) {
          changes.forEachChangedItem((elt) => {
            if (elt.key === 'firstName' || elt.key === 'lastName' ) {
              this.person.fullName = this.person.firstName + ' ' + this.person.lastName;
            }
          });
        }
      }
    }
    

    当prop1属性的值被更新时,doSomethingIfProp1Change方法被调用。

    看到这个 plunkr:http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview。

    【讨论】:

    • 好的,谢谢!顺便说一句,第二种解决方案是监听数组变化的唯一方法吗?
    • 太棒了!是的,对于数组和对象内的更改,这是 Angular2 中的唯一方法。例如 ngFor 和 ngClass 依赖于这种机制 ;-) ngOnChanges 不适用于这种情况......
    • 最新的角度版本似乎不再是这种情况。我看到 ngDoCheck 在相当大的更新滞后后被触发
    猜你喜欢
    • 2017-06-27
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 2014-12-20
    • 2021-01-09
    • 1970-01-01
    相关资源
    最近更新 更多