用@Output装饰器为Angular中的组件定义事件

用@Input装饰器为Angular中的组件传值中,给大家介绍了如何通过@Input装饰器向组件(Component)传递参数,在本文中将会给大家介绍如何自定义组件的事件,如何响应事件,又如何通过事件来接收数据。

定义自定义事件

假设我们正在开发一个个人待办事项管理的应用,其中我们定义一个TodoComponet, 职责是在在界面上显示、编辑一个代办事项(Todo)。如何给这个组件传值,我们已经在文章用@Input装饰器为Angular中的组件传值中为大家介绍了,那如果TodoComponent想要抛出一个事件,比如当删除一个Todo的时候,需要通知其它组件自己被删除了,这该怎么做呢?在Angular中,可以使用@Output装饰器来为组件声明一个可以抛出的事件,也就是我们常说的为组件添加一个自定义事件。让我们来看代码

组件类定义文件: todo.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnInit {

@Output()
deleteEvent = new EventEmitter();

constructor() { }

ngOnInit() {
}

onDelete() {
this.deleteEvent.next();
}
}

从组件类代码的定义我们可以看到,自定义事件的定义要使用到一个装饰器 - @Output 和一个类 EventEmitter。在上面的代码中,我们通过声明一个属性的方式来声明一个自定义事件,属性名就是事件名
组件模板文件: todo.component.html

1
2
3
4
5
6
7
8
9
10
11
12
<div class="card">
<div class="card-head">
{{todo.title}}
</div>
<div class="card-content">
{{todo.desc}}
{{todo.done}}
</div>
<div class="card-footer">
<button (click)="onDelete()">Delete</button>
</div>
</div>

在组件的模板代码中,我们增加了一个Delete按钮并绑定了一个onDelete的函数作为按钮按下时的响应函数,模拟删除的动作。结合两部分的代码我们可以看到,当用户按下Delete时,会执行this.deleteEvent.next()把定义的事件抛出去(触发)。我们再来看看使用Todo组件的代码

页面模板代码: todo-page.component.html

1
2
3
<div *ngFor = "let todo of todos">
<app-todo [todo]="todo" (deleteEvent)="onDeleteEvent()"></app-todo>
</div>

在模板代码中,我们通过()将自定义事件 - deleteEvent绑定到函数onDeleteEvent()上。函数在对应的类代码中定义

页面类代码: todo-page.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component({
selector: 'app-todo-page',
templateUrl: './todo-page.component.html',
styleUrls: ['./todo-page.component.css']
})
export class TodoPageComponent implements OnInit {

todos: Todo[];

constructor() {}


ngOnInit() {
}

onDeleteEvent() {
console.log('onDeleteEvent..');
}
}

运行程序后,当Todo组件中的Delete按钮被按下,我们可以在浏览器的Javascript控制台看到’onDeleteEvent..’被输出出来。这样就完成了组件自定义事件的定义,触发和处理。

在自定义事件中传参

在Angular中,为自定义事件传递参数非常简单,直接在触发事件调用”next”函数时,带上参数就可以了。比如在我们的例子中,我们希望在自定义事件中把当前的Todo项作为事件参数传出去,就可以简单的调用”next(this.todo)”。修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnInit {

@Input()
todo: Todo;

@Output()
deleteEvent = new EventEmitter();

constructor() { }

ngOnInit() {
}

onDelete() {
this.deleteEvent.next(this.todo);
}

}

注意第20行,next函数调用的参数
在接收时,需要使用Angular中的一个特别变量: $event。 修改后的代码如下
页面模板代码: todo-page.component.html

1
2
3
<div *ngFor = "let todo of todos">
<app-todo [todo]="todo" (deleteEvent)="onDeleteEvent($event)"></app-todo>
</div>

注意第2行代码,$event变量的使用

页面类代码: todo-page.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component({
selector: 'app-todo-page',
templateUrl: './todo-page.component.html',
styleUrls: ['./todo-page.component.css']
})
export class TodoPageComponent implements OnInit {

todos: Todo[];

constructor() {}


ngOnInit() {
}

onDeleteEvent(event) {
console.log('onDeleteEvent..');
console.log('Event data = ' + JSON.stringify(event));
}
}

注意第16行开始的onDeleteEvent函数

本文标题:用@Output装饰器为Angular中的组件定义事件

文章作者:晨星

发布时间:2019年05月31日 - 20:05

最后更新:2020年09月16日 - 08:09

原始链接:https://www.mls-tech.info/web/angular/angular-component-event/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。