检测组件的输入属性的角度何时发生变化

时间:2018-07-15 16:10:26

标签: angular

我有一个角度分量,其输入为Person

export class Person {
  public name = 'Initial Name';
}

export class PersonComponent implements OnInit, OnChanges {
  @Input() public person: Person;

  ngOnChanges(changes: SimpleChanges): void {
    console.log('changed');
  }
}

在该组件的父组件中,如果我替换作为子组件输入的Person对象,则会在子组件中触发ngOnChanges()

但是,如果仅从父组件更改name对象的Person,则ngOnChanges()不会在子组件中被触发(无论如何,如果我绑定了人子模板中的html元素的名称,它将被更新)。

更改输入属性时,是否有任何方法可以在子组件中得到通知?

4 个答案:

答案 0 :(得分:3)

否,只有在引用发生更改时才会触发ngOnChanges挂钩。通过更改父组件中的name属性,可以轻松实现目标:

this.person = {...this.person, name: 'new value'};

答案 1 :(得分:2)

您总是可以在Person上创建一个Observable,只要属性发生更改,该Observable就会发出。

从“ rxjs”导入{Subject};

export class Person {

  private _changes = new Subject<any>();
  private _name = 'Initial Name';

  // subscribe to this one
  public changes = this._changes.asObservable();

  set name(newName: string) {
    this._name = newName;
    this._changes.next({'name': newName});
  }

  get name() {
    return this._name;
  }

}

这样,您可以订阅person.changes,每次更改name时,该值都会发出一个值

当您编写person.name = 'Fred'时,将调用setter,后者又将从Observable中发出新值。

答案 2 :(得分:0)

您为什么需要您的孩子了解这一变化?在您的孩子中,您应该只更改与孩子有关的事物,并将其冒充给父母。使用Observables,孩子仍然可以轻松显示信息。我建议使用@Output,然后在父对象中更改对象

答案 3 :(得分:-1)

如果使用吸气剂,则每次输入值时都会执行setter。因此,解决方法可以是两个变量

  @Input() person;
  @Input() 
  set changePerson(value)
  {
    console.log(this.person);
  }

所以,在你父母那里你可以写

  <app-child [person]="person" [changePerson]="changePerson"></app-child>

  this.person.name="new name";
  this.changePerson=true;

另一个选项是在每次更改

时在服务中使用EventEmitter
    //Our service
    @Injectable({
      providedIn: 'root',
    })
    export class ChangeService {
      changed: EventEmitter<any>=new EventEmitter();
      emit(value:any)
      {
          this.changed.emit(value);
      }
    }

//Our parent
constructor (private changeService:ChangeService){}
  ngOnInit()
  {
    setTimeout(()=>{
      this.changeService.emit(this.person)

    })
    setTimeout(()=>{
      this.person.name="George";
      this.changeService.emit(this.person);
    },5000);
  }

//Our child
  person:any;
  ngOnInit() {
    this.changeService.changed.subscribe(res=>{
      this.person=res;
      console.log(res);
    })
  }