Angular应用里的@Input和@Output注解使用方法介绍

191 阅读2分钟

这一对注解用于在parent上下文和子指令或者组件之间共享数据。@Input修饰的属性可写,用于数据绑定,而@Output属性可被订阅(Observable).

@Input() and @Output() allow Angular to share data between the parent context and child directives or components. An @Input() property is writable while an @Output() property is observable.

假设有这样一对父子Component:

<parent-component>
  <child-component></child-component>
</parent-component>

可以把@Input和@Output想象成一对API, 父子组件间通过API进行通信。@Input相当于inbound接口,允许数据流入子Component,而@Output允许子Component往外发送数据。

@Input() and @Output() act as the API, or application programming interface, of the child component in that they allow the child to communicate with the parent. Think of @Input() and @Output() like ports or doorways—@Input() is the doorway into the component allowing data to flow in while @Output() is the doorway out of the component, allowing the child component to send data out.

Use the @Input() decorator in a child component or directive to let Angular know that a property in that component can receive its value from its parent component. It helps to remember that the data flow is from the perspective of the child component. So an @Input() allows data to be input into the child component from the parent component.

如何理解Angular这对input和output的流向?类似SAP CRM中间件里的download和upload. 在SAP中间件里,我们谈论数据流向时,视角是从SAP CRM出发的,凡是数据从ERP流向CRM,即CRM从ERP下载数据,所以称为download. 反之,从CRM推送数据到ERP,称为upload.

而Angular里的@input和@output,视角同样是从child Component来说的。


被@Input修饰的子Component属性,可以使用Angular生命周期hook OnChanges来监控。

@Output

被@output修饰的子Component属性,一般通过Angular EventEmitter初始化,通过events的方式流出子Component.

An @Output() property should normally be initialized to an Angular EventEmitter with values flowing out of the component as events.

例子:

子Component里定义一个property:

@Output() newItemEvent = new EventEmitter();

如何通过Event的方式发送数据给parent Component?

export class ItemOutputComponent {

  @Output() newItemEvent = new EventEmitter<string>();

  addNewItem(value: string) {
    this.newItemEvent.emit(value);
  }
}

child Component的html:

<label>Add an item: <input #newItem></label>
<button (click)="addNewItem(newItem.value)">Add to parent's list</button>

如何在parent Component里接收来自child Component的事件?

<app-item-output (newItemEvent)="addItem($event)"></app-item-output>

newItemEvent是子Component加了@Output注解的property名称,addItem是父Component的事件处理函数:

export class AppComponent {
  items = ['item1', 'item2', 'item3', 'item4'];

  addItem(newItem: string) {
    this.items.push(newItem);
  }
}

要获取更多Jerry的原创文章,请关注公众号"汪子熙":