【问题标题】:Observable of Component Attribute Changes in Angular2Angular2 中组件属性变化的可观察性
【发布时间】: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() });
    }
}

【问题讨论】:

    标签: javascript angular rxjs angular2-directives


    【解决方案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(); }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-27
        • 2017-09-07
        • 2013-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        相关资源
        最近更新 更多