这一对注解用于在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修饰的子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();
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 listbutton>
如何在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的原创文章,请关注公众号"汪子熙":