【问题标题】:Angular 2: how do I detect attribute changes to input attributes on a Component?Angular 2:如何检测组件上输入属性的属性更改?
【发布时间】:2016-12-13 16:33:15
【问题描述】:

我有一个 Angular 2 控制器,看起来像这样:

@Component({
  selector: 'my-component',
  template: '<div>The value is: {{ value }}</div>',
})
class MyComponent implements OnInit {
  @Input()
  value: string;

  @Output
  valueChange = new EventEmitter<number>();

  ngOnInit() {
    this.valueChange.subscribe(value => {
      console.log('new value:', value); // <-- does not get triggered
    });
  }
}

但是当value的值从模板绑定改变时:

<my-component [value]="someValue" /> <!-- valueChange not triggered! -->

valueChange 事件未被触发,因此即使模板正确更新并显示新值,组件也不知道它已被更改。

如何检测控制器上的输入属性何时更改?

【问题讨论】:

    标签: angular


    【解决方案1】:

    在我看来,Output 是为了让您的组件向其他人发出事件,以便他们在必要时更新他们的视图,它应该只用于内部进行的需要广播的更改(因此名称为 Output )。在Input 更改上触发Output 事件可能会导致意外行为(因为现在所有内部和外部更改都会触发valueChange,而不是真正的Output)。

    在您的情况下,如果您想在您的 value 更改时做一些事情,您可以将其设为 setter:

    private _value: string;
    get value(): string {
      return this._value;
    }
    
    @Input('value')
    set value(val: string) {
      this._value = val;
      console.log('new value:', value); // <-- do your logic here!
    }
    

    【讨论】:

      【解决方案2】:

      我使用 setter 来检测输入变量何时被修改。您必须在 @Component 装饰器中使用 inputs 键而不是 @Input 声明才能使其工作,如下所示:

      @Component({
        selector: 'my-component',
        template: '<div>The value is: {{ value }}</div>',
        inputs: ['value']
      })
      class MyComponent {
        private _value: string;
      
        @Output
        valueChange = new EventEmitter<number>();
      
        set value(value) {
          this._value = value;
          console.log('new value:', value);
          this.valueChange.emit(value);
        }
      
        get value(value) {
          return this._value;
        }
      }
      

      也仅供参考,类方法是ngOnInit 而不是onInit

      【讨论】:

      • 你可以在\@Component 装饰器上使用inputs 属性或者你可以在set 属性上使用\@Input 装饰器。它们目前都可以工作,并且 \@Input 装饰器似乎是当前的首选方式
      • 一个get访问器应该也不能有一个值,你可能想把你的get方法更新为get value() {}我认为你的@output也可能需要更新为@Output()
      【解决方案3】:

      我已经能够通过从OnChanges 实施来解决这个问题:

      ngOnChanges(changes) {
        for (let key in changes) {
          if (this[key + 'Change'])
            this[key + 'Change'].emit(changes[key].currentValue);
        }
      }
      

      每当 Angular 检测到更改时,它会自动触发 Change 事件……但有什么方法可以在本地做到这一点?

      【讨论】:

        猜你喜欢
        • 2019-06-13
        • 2016-11-11
        • 2018-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 2017-11-11
        • 2017-08-15
        相关资源
        最近更新 更多