@Input

组件或指令需要接收一个外部的数据,这是理所当然的。

长什么样?

通过 @Input() 装饰器,告知这个属性允许外部提供数据。

@Component({
  selector: 'user-detail',
  template: `<p>user id: {{userId}}</p>`
})
export class UserDetailComponent {
  @Input() userId: number;
}

于是,需要用到 user-detail 组件,都可以向它传递一个 userId 值。

<user-detail [userId]="uid">

属性太难看了

是的,和我一样有洁癖的,是不会允许 [userId] 的写法和 user-detail 这种写法不搭。

我认知的写法应该是这样:

<user-detail [user-id]="uid">

这样看起来才爽。但,等等,user-detail 也应该换一下。

@Input('user-id') userId: number;

监听变更

用户ID user-id 属性值是由外部传递进来的,但当传递一个小于0的值时是无任何意义,或者说,我们并不希望接收到一个小于0数值时,怎么办?

方法一:get & set

ts 语言支持利用getters/setters来控制对成员的访问,因此,我们可以利用这一点。

private _uid: number;

@Input('user-id')
set userId(uid: number): void {
    if (uid <= 0) throw new Error('invalid uid');
    this._uid = uid;
}
get userId(): number {
    return this._uid;
}

方法二:ngOnChanges 钩子

需要实现 OnChanges 接口,这样 Angular 将会主动调用 ngOnChanges 钩子,SimpleChanges 参数会包括所有变更的属性值。

@Component({
  selector: 'user-detail',
  template: `<p>{{user.name}}</p>`
})
export class UserDetailComponent implements OnChanges {
  @Input('user-id') userId: number;

  ngOnChanges(changes: SimpleChanges): void {
    if ('userId' in changes) {
      // changes.userId.firstChange 是否第一次变更
      // changes.userId.currentValue 变更后值
      // changes.userId.previousValue 变更前值
    }
  }
}

二者区别

都可以达到监听变更后的新值,但有很大的区别。

  • get & set 只对当前属性有效。
  • ngOnChanges 对多个属性变更后才会触发通知,因此,参数接收到的是所有变更属性值集合对象。

因此,如果你对单一个的变更监听前者更适宜,反之。

results matching ""

    No results matching ""