Angular 中的 @Input 和 @Output





4.00/5 (4投票s)
Angular 中的 @Input 和 @Output
Input 和 Output 是 Angular 中用于在两个组件之间进行通信的两个装饰器。
在这篇文章中,我们将研究如何使用 @Input
将数据传递到组件,以及如何使用 @Output
将数据流回。
正如我上面提到的,@Input
和 @Output
是装饰器。 那么什么是装饰器呢?
装饰器 (Decorator)
装饰器是一个函数,它以 @
为前缀调用,后跟类、方法、属性。
Ex
@Input()
description: string;
如何传递数据?
在我们开始编写 Input 和 Output 装饰器之前,让我们看看如何将数据传递到任何组件。
假设我们有两个组件 parent
和 child
。 child 的选择器是 child-comp
。 现在,如果在父组件中,我们只需在父组件模板内的标记中添加一个属性。
import { Component } from '@angular/core' @Component({ selector: 'my-app', template: ` <child-comp [parentCount]="count"></child-comp> ` }) export class App { count: number = 10; }
因此,parentCount
是子元素的 @Input
绑定,fullName
是具有数据的本地组件的属性。
@Input
@Input
装饰器用于获取从组件传递的数据。
让我们继续上面的例子。 现在,我们有来自父组件的数据,我们必须使用 @Input
在子组件中捕获数据。
我们要做的就是添加一个变量,名称为 parentCount
,并使用它来绑定模板中的元素
例如: @Input() parentCount: number;
因此,子组件将如下所示。
import { Component, Input } from '@angular/core'; @Component({ selector: 'child-comp', template: ` <div> {{ parentCount }} </div> ` }) export class ChildComponent { @Input() parentCount: number; }
不要忘记将我们的子组件添加到 @NgModule
的 declarations 部分。
@Input 中的别名
我们可以对来自组件的数据进行别名。 如上面的示例,我们可以像这样对 parentCount
进行别名
@Input('parentCount') count: number
现在,我们将拥有 count
变量中的数据。 基本上,如果我们有相同的变量名,可能会在子组件中发生冲突,我们可以将其别名为不同的名称。
@Output
到目前为止,我们只看到了以单向方式传递数据,即从父组件到子组件。 现在,让我们看看如何在父子之间建立有状态的连接。
@Output
不仅仅是可以将数据从子组件传递回父组件的单一事物。 我们必须使用 EventEmitter
向父组件发出事件,以便父组件可以捕获公开的事件并检索数据。
我们必须结合使用 @Input
装饰器将初始数据传递到子组件,并使用 @Output
装饰器和事件发射器获取返回的更新数据。
让我们扩展上面的 @Input
装饰器的功能,将更新的内容推送回父组件并在父组件中显示更新的值。
//import Output, EventEmitter from angular core import {Component, Input, Output, EventEmitter} from '@angular/core' //define the event emitter @Output() change: EventEmitter<number> = new EventEmitter<number>(); //emit the event with the above change event this.change.emit(11); //11 will be emitted to the parent
在上面的代码中,我们需要导入 Input, Output, EventEmitter 才能从子组件推送到父组件。
我们声明了一个 change 事件,它的类型是 EventEmitter
,它推送一个 number 类型的数据。 请注意,change 只是我们为事件发射器提供的事件。 它既不是约定,也不是关键字。 你也可以有任何自定义名称。 我鼓励你在演示代码中将 change
事件名称更改为任何自定义名称,并确保它有效。
事件发射器将具有 emit()
方法来发射到父组件。 每当应通知父组件该更改时,调用最后一行。
import {Component} from '@angular/core' //import the child component import {ChildComponent} from 'src/child.component' //add (change) event to the child component selector. //(change) is the name of the event that is emitted from the child component @Component({ selector: 'parent', template: ` <child-comp [parentCount]="count" (change)="updateFromChild($event)"></child-comp> ` }); export class ParentComponent { count: number = 0; //initial value of count //This is the event that we subscribe to the child's selector //We will receive the data from child in this function updateFromChild($event){ this.count++; } }
因此,对于父组件,我们将简单地将该 EventEmitter
的事件添加到此处的子组件选择器(它是 child-comp
)。 正如你所看到的,我已将 (change)
事件添加到标签,并提供了一个可以在事件发出时接收的方法。
updateFromChild
方法上的 $event
参数将具有从发出事件的组件发送的内容。
尽管这只是为了在父组件和子组件之间来回传递数据,但需要进行大量设置才能实现。 但是一旦习惯了,这看起来在 Angular 中非常简单易行。