组件(指令)间通信是Angular中一个非常常见的需求,对于有直接嵌套关系(比如父子组件)的组件,我们可以使用@Input和@Output来实现通信,但是对于没有嵌套关系的组件(亦或者嵌套层级很深的组件),我们就需要使用其他的方法来实现通信了,比如使用服务来实现组件间通信。
下面这个例子就是两个没有嵌套关系的指令之间通信的例子,我们将使用服务来实现这个功能。
注意:在Angular中,组件和指令是一样的,组件是一种特殊的指令。
Create a service
首先我们需要创建一个服务,用于组件间通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import { Injectable } from '@angular/core'; import { Subject } from 'rxjs';
@Injectable({ providedIn: 'root' }) export class CommunicationService { private messageSource = new Subject<string>();
public message$ = this.messageSource.asObservable();
sendMessage(message: string) { this.messageSource.next(message); } }
|
Directive(Send message)
该指令使用上面定义的service发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { Directive, HostListener } from '@angular/core'; import { CommunicationService } from './communication.service';
@Directive({ selector: '[senderDirective]' }) export class SenderDirective { constructor(private communicationService: CommunicationService) {}
@HostListener('click') onClick() { this.communicationService.sendMessage('Hello from sender directive!'); } }
|
Directive(Receive message)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 该指令使用上面定义的service接收消息 import { Directive } from '@angular/core'; import { CommunicationService } from './communication.service';
@Directive({ selector: '[receiverDirective]' }) export class ReceiverDirective { constructor(private communicationService: CommunicationService) { this.communicationService.message$.subscribe(message => { console.log('Received message:', message); }); } }
|
AppModule
我们需要在appModule中声明这两个指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component'; import { CommunicationService } from './communication.service'; import { SenderDirective } from './sender.directive'; import { ReceiverDirective } from './receiver.directive';
@NgModule({ declarations: [ AppComponent, SenderDirective, ReceiverDirective ], imports: [ BrowserModule ], providers: [CommunicationService], bootstrap: [AppComponent] }) export class AppModule { }
|
Usage
1 2
| <button senderDirective>Send message</button> <div receiverDirective></div>
|