Angular2 中组件属性变化的可观察性

Posted

技术标签:

【中文标题】Angular2 中组件属性变化的可观察性【英文标题】:Observable of Component Attribute Changes in Angular2 【发布时间】:2017-05-07 13:48:03 【问题描述】:

当在 Angular 2 中创建一个通过 @Input 具有输入属性的组件时,我如何从对该属性 @Input 所做的更改中获取可观察值(不要与用户表单输入混淆)。

export class ExampleComponent implement OnChanges
    @Input() userObject: User;

    ngOnChanges(changes: any): void
        // Validate that its the 'userObject' property first
        this.doStuff()
    

在实践中,我希望将 userObject 的 Observable 更改与其他事物的 Observable 更改合并,以获得流畅的更改反应模式。

export class ExampleComponent implement OnChanges
    @Input() userObject: User;

    constructor():
        userObject.valueChanges.subscribe(x=> this.doStuff() );
    

【问题讨论】:

【参考方案1】:

尝试使用 get 和 set,下面的 valueChanges() 将在设置时触发。

  private _userObject: User;
  @Input()
  set userObject(userObject: User) 
    this._userObject = userObject;
    this.valueChanges();
  
  get userObject(): User 
    return this._userObject;
  

使用 Observable:

  private userObjectChange = new Subject<User>();
  userObjectChange$ = this.userObjectChange.asObservable();

  private _userObject: User;
  @Input()
  set userObject(userObject: User) 
    this.userObjectChange.next(userObject);
    this._userObject = userObject;
  
  get userObject(): User 
    return this._userObject;
  

订阅:

this.newQuote.subscribe(user => ...)

【讨论】:

我也知道这种方式。我的重点是获得一个实际的 Observable 更改,以便它可以轻松地与我在此组件上发生的其他更改流合并。 您可以将上面的 valueChange 替换为 EventEmitter 事件 谢谢!如果我有权限,我会赞成这个答案!【参考方案2】:

您可以为此使用主题:

export class ExampleComponent 
    @Input() set userObject(userObject: User) 
       this.userObject$.next(userObject);
    

    private userObject$ = new Subject<User>();

    constructor():
        this.userObject$.subscribe(x=> this.doStuff() );
    

【讨论】:

我认为这是最有意义的答案/方法。我认为我的问题是我认为这已经是预先构建的感觉,他们正在推动如此多的变化。谢谢@sergey-sokolov【参考方案3】:

检查输入变化的最佳方法实际上是使用ngOnChanges 生命周期。

ngOnChanges(changes:  [propertyName: string]: SimpleChange ) 
  const changedInputs = Object.keys(changes);
  // Only update the userObject if the inputs changed, to avoid unnecessary DOM operations.
  if (changedInputs.indexOf('userObject') != -1) 
  // do something
      

参考:https://github.com/angular/material2/blob/master/src/lib/icon/icon.ts#L143

【讨论】:

【参考方案4】:

我发现 BehaviorSubject 类最适合这种情况。您可以使用 BehaviorSubject 的 getValue 函数在当前值处达到峰值,而不是创建单独的后端字段。然后使用支持的 BehaviorSubject 将其视为更改的可观察对象。

export class ExampleComponent
    private _userObject: BehaviorSubject<User> = new BehaviorSubject<User>(null);

    @Input()
    set userObject(value: User):  this._userObject.next(value); 
    get userObject(): User  return this._userObject.getValue(); 

【讨论】:

以上是关于Angular2 中组件属性变化的可观察性的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 beta.12 和 RxJs 5 beta.3 的可观察到的错误

带有引导事件的 Angular2 不会触发可观察到的变化

绑定到angular2中的组件属性

Angular 2:如何检测数组中的变化? (@input 属性)

统一的可观察性:指标日志和跟踪

尽管可观察到的变化,但计算的可观察到的不会触发