Angular 2属性绑定意外触发

时间:2019-04-03 14:41:50

标签: angular eventemitter

我有一个组件可以编辑日期范围(生效日期和到期日期)。当任何一个日期更改时,它将发出新的日期范围。但是,发射后,@Input() set dateRange(...)被调用。这是预期的行为吗?如果是这样,当父组件刚刚从子组件获取新值时,为什么还要设置绑定的子组件属性?

export class EditDateRange {
  effectiveDate?: Date;
  expireDate?: Date;

  @Output() dateRangeChange = new EventEmitter<DateRange>();

  @Input()
  get dateRange(): DateRange {
    return new DateRange({
      effectiveDate: this.effectiveDate,
      expireDate: this.expireDate,
    });
  }

  // Gets called when dateRangeChange emitts an event
  set dateRange(dateRange: DateRange) {
    if (dateRange.hasEffectiveDate) {...}
    if (dateRange.hasExpireDate) {...}
  }

  dateRangeChanged() {
    this.dateRangeChange.emit(this.dateRange);
  }
}

然后在父HTML中

<div>
    ...
    <edit-date-range [(dateRange)]="dateRange" 
                     (dateRangeChange)="validateDateRange($event)">
    </edit-date-range>
</div>

当我将[(dateRange)]更改为[dateRange]时,问题(或行为)消失了。

2 个答案:

答案 0 :(得分:0)

setTimeout将是两种方式的绑定,并且已经是用于检测更改的生命周期挂钩,因此它的行为符合预期。 [(dateRange)]是一种绑定方式,不再充当生命周期挂钩。与其手动处理事件发出,不如使用ngOnChanges来利用已经在发挥作用的生命周期挂钩。

答案 1 :(得分:0)

来自ngModel banana in box documentation

  

当元素具有名为x的可设置属性和名为xChange的相应事件时,[[x)]语法很容易演示。   <app-sizer [(size)]="fontSizePx"></app-sizer>

更远的地方:

  

双向绑定语法实际上只是属性绑定和事件绑定的语法糖。角度将SizerComponent绑定到其中:   <app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>

话虽如此,使用双向绑定和更改事件绑定将导致更改被触发两次。