Слушать изменения на объекте в Angular2/машинопись

в Angular2 / Typescript можно "наблюдать" поле объекта для изменений.

например, скажем у меня есть класс Person с полями firstName, lastName и fullName. Возможно ли автоматическое обновление fullName когда-либо firstName или lastName изменения?

что-то вроде этого:

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}`;
  }
}

1 ответов


первый подход

вы можете использовать TypeScript setters / getters как описано ниже, чтобы синхронизировать 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 по умолчанию не позволяет определить изменение свойств внутри объектов. Он обнаруживает только обновления по ссылкам. Я имею в виду, если ссылка (или значение для примитивных типов) связанного свойства обновляется.

что bien сказал, 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.