65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular 中的 @Input 和 @Output

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2017年8月10日

CPOL

3分钟阅读

viewsIcon

74455

Angular 中的 @Input 和 @Output

Input 和 Output 是 Angular 中用于在两个组件之间进行通信的两个装饰器。

在这篇文章中,我们将研究如何使用 @Input 将数据传递到组件,以及如何使用 @Output 将数据流回。

正如我上面提到的,@Input@Output 是装饰器。 那么什么是装饰器呢?

装饰器 (Decorator)

装饰器是一个函数,它以 @ 为前缀调用,后跟类、方法、属性。

Ex

@Input()

description: string;

如何传递数据?

在我们开始编写 Input 和 Output 装饰器之前,让我们看看如何将数据传递到任何组件。

假设我们有两个组件 parentchild。 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 中非常简单易行。

© . All rights reserved.