在前面的章节中,我们讨论了如何创建基本组件的模板和样式。组件是Angular应用中的重要构件,不同组件之间的交互是构建一个有效、可维护的应用程序的重要部分。本章将专注于组件之间的交互方式,包括输入属性、输出属性和服务。
1. 组件交互的基本概念
在Angular中,组件之间的交互主要通过输入属性(@Input)和输出属性(@Output)进行。它们分别用于接收数据和向父组件发送事件。
@Input
装饰器用于定义属性,以便父组件可以向子组件传递数据。
@Output
装饰器用于定义事件,以便子组件可以向父组件发送通知或数据。
通过@Input
,我们可以让父组件向子组件传递数据。以下是一个简单的示例:
1 2 3 4 5 6 7 8 9 10
| import { Component, Input } from '@angular/core';
@Component({ selector: 'app-child', template: `<p>子组件接收到的数据: {{ data }}</p>` }) export class ChildComponent { @Input() data: string; }
|
在这个示例中,ChildComponent
接收一个名为 data
的字符串。父组件可以使用这个组件并向其传递数据:
1 2 3 4 5 6 7 8 9 10 11
| import { Component } from '@angular/core';
@Component({ selector: 'app-parent', template: `<h1>父组件</h1> <app-child [data]="parentData"></app-child>` }) export class ParentComponent { parentData = '来自父组件的数据'; }
|
在ParentComponent
中,我们使用app-child
选择器来插入子组件,并通过[data]="parentData"
传递数据。
1.2 输出属性(@Output)
@Output
用于子组件向父组件发送事件通知。我们通常通过EventEmitter
来实现这一点。以下是一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { Component, EventEmitter, Output } from '@angular/core';
@Component({ selector: 'app-child', template: `<button (click)="onButtonClick()">点击我</button>` }) export class ChildComponent { @Output() childEvent = new EventEmitter<string>();
onButtonClick() { this.childEvent.emit('子组件按钮被点击了!'); } }
|
在这个示例中,ChildComponent
中定义了一个名为 childEvent
的事件,点击按钮时会触发该事件并向父组件发送消息。
父组件如何监听这个事件呢?
1 2 3 4 5 6 7 8 9 10 11
| @Component({ selector: 'app-parent', template: `<h1>父组件</h1> <app-child (childEvent)="handleChildEvent($event)"></app-child>` }) export class ParentComponent { handleChildEvent(message: string) { console.log(message); } }
|
在ParentComponent
中,使用(childEvent)="handleChildEvent($event)"
来监听来自子组件的事件,并在事件发生时调用handleChildEvent
方法。
2. 通过服务进行组件间通信
除了使用输入和输出属性外,Angular中的服务也是一种重要的组件间通信手段。服务可以在多个组件之间共享数据或状态,非常适合于需要跨多个组件进行通信的场景。
2.1 创建服务
我们可以通过Angular CLI生成一个服务:
1
| ng generate service shared
|
下面是一个简单的共享服务示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root', }) export class SharedService { private messageSource = new BehaviorSubject<string>('默认消息'); currentMessage = this.messageSource.asObservable();
changeMessage(message: string) { this.messageSource.next(message); } }
|
2.2 在组件中使用服务
接下来,我们可以在组件中注入这个服务并使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { Component } from '@angular/core'; import { SharedService } from './shared.service';
@Component({ selector: 'app-child', template: `<button (click)="sendMessage()">发送消息</button>` }) export class ChildComponent { constructor(private sharedService: SharedService) {}
sendMessage() { this.sharedService.changeMessage('来自子组件的消息!'); } }
|
在ChildComponent
中,当按钮被点击时,会调用sendMessage
方法,改变服务中的消息。
然后在父组件中,我们可以订阅这个消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { Component, OnInit } from '@angular/core'; import { SharedService } from './shared.service';
@Component({ selector: 'app-parent', template: `<h1>父组件</h1> <p>消息: {{ message }}</p>` }) export class ParentComponent implements OnInit { message: string;
constructor(private sharedService: SharedService) {}
ngOnInit() { this.sharedService.currentMessage.subscribe(message => this.message = message); } }
|
在ParentComponent
中,我们使用ngOnInit
生命周期钩子订阅服务的消息,并在消息变化时更新组件的状态。
3. 小结
本章介绍了Angular中组件之间交互的主要方法,包括输入属性、输出属性和服务。通过这些方法,我们可以实现组件之间的高效通信,提高组件的复用性与可维护性。
在下一章,我们将深入探讨Angular中的数据绑定概念,了解如何在组件与视图间流畅地传递数据。