如果你想用 Angular 来使用 BroadcastChannel,你可以参考一些网上的例子,比如:
¹: How to use the BroadcastChannel API with Angular - ACA Group
²: Angular BroadcastChannel: Send Data between Two Browser Tabs, Property does not exist on type ‘BroadcastChannel’ - Stack Overflow
³: Angular 16 + Broadcast channel | by @techshareskk (Sai Kumar Korthivada) | Medium
⁴: Getting to Know the Broadcast Channel API in JavaScript
大致的思路是:
- 在你的 Angular 项目中,创建一个服务(service)来封装 BroadcastChannel 的创建、发送和接收消息的逻辑。
- 在你需要使用 BroadcastChannel 的组件(component)中,注入这个服务,并调用它的方法来发送或接收消息。
- 使用箭头函数(arrow function)来定义 onmessage 的回调函数,以保持 this 的指向正确。
- 在发送或接收消息时,可以使用一个类型(type)字段来区分不同的消息类型,以便进行相应的处理。
下面是一个简单的示例代码,你可以根据你的具体需求进行修改:
broadcast.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class BroadcastService {
// 定义一个私有属性来存储 BroadcastChannel 对象
private broadcastChannel: BroadcastChannel;
constructor() {
// 创建一个 BroadcastChannel 对象,命名为 "my_channel"
this.broadcastChannel = new BroadcastChannel('my_channel');
}
// 定义一个方法来发送消息
sendMessage(message: any) {
this.broadcastChannel.postMessage(message);
}
// 定义一个方法来接收消息
onMessage(callback: (message: any) => void) {
this.broadcastChannel.onmessage = (ev) => {
callback(ev.data);
};
}
}
sender.component.ts
import { Component, OnInit } from '@angular/core';
import { BroadcastService } from '../broadcast.service';
@Component({
selector: 'app-sender',
templateUrl: './sender.component.html',
styleUrls: ['./sender.component.css']
})
export class SenderComponent implements OnInit {
// 定义一个属性来存储输入框的值
input: string;
constructor(private broadcastService: BroadcastService) { }
ngOnInit(): void {
}
// 定义一个方法来发送消息
send() {
if (this.input) {
// 调用服务的方法来发送消息,带上类型和数据
this.broadcastService.sendMessage({
type: 'text',
data: this.input
});
// 清空输入框的值
this.input = '';
}
}
}
sender.component.html
<div class="container">
<h1>Sender</h1>
<div class="form-group">
<label for="input">Enter your message here</label>
<input id="input" type="text" class="form-control" [(ngModel)]="input" placeholder="Hello world">
</div>
<button class="btn btn-primary" (click)="send()">Send</button>
</div>
receiver.component.ts
import { Component, OnInit } from '@angular/core';
import { BroadcastService } from '../broadcast.service';
@Component({
selector: 'app-receiver',
templateUrl: './receiver.component.html',
styleUrls: ['./receiver.component.css']
})
export class ReceiverComponent implements OnInit {
// 定义一个属性来存储接收到的消息
messages: string[] = [];
constructor(private broadcastService: BroadcastService) { }
ngOnInit(): void {
// 调用服务的方法来接收消息,并传入一个回调函数
this.broadcastService.onMessage((message) => {
// 判断消息的类型是否是 "text"
if (message.type === 'text') {
// 把消息的数据添加到 messages 数组中
this.messages.push(message.data);
}
});
}
}
receiver.component.html
<div class="container">
<h1>Receiver</h1>
<div *ngIf="messages.length > 0">
<p *ngFor="let message of messages">{{ message }}</p>
</div>
<div *ngIf="messages.length === 0">
<p>No messages yet</p>
</div>
</div>
这样,当你在 sender 组件输入一条消息并点击发送按钮时,receiver 组件就会收到这条消息并显示出来。你可以试试看效果。😊
Source: Conversation with Bing, 2023/7/28
(1) How to use the BroadcastChannel API with Angular - ACA Group. https://www.acagroup.be/en/blog/how-to-use-the-broadcastchannel-api-angular/.
(2) typescript - Angular BroadcastChannel: Send Data between Two Browser … https://stackoverflow.com/questions/62827047/angular-broadcastchannel-send-data-between-two-browser-tabs-property-does-not.
(3) Angular 16 + Broadcast channel | by @techshareskk (Sai Kumar Korthivada … https://techshareskk.medium.com/angular-16-broadcast-channel-4049a7f46019.
(4) Getting to Know the Broadcast Channel API in JavaScript. https://netbasal.com/getting-to-know-the-broadcast-channel-api-in-javascript-67e1603ff555.
如果你想在打开新窗口的初期表示就接收到消息,你可以在 receiver 组件的 ngOnInit 方法中调用一次 sendMessage 方法,向 sender 组件发送一个特殊的消息,比如:
ngOnInit(): void {
// 调用服务的方法来发送一个 "ready" 消息
this.broadcastService.sendMessage({
type: 'ready'
});
// 调用服务的方法来接收消息,并传入一个回调函数
this.broadcastService.onMessage((message) => {
// 判断消息的类型是否是 "text"
if (message.type === 'text') {
// 把消息的数据添加到 messages 数组中
this.messages.push(message.data);
}
});
}
然后,在 sender 组件的 onMessage 回调函数中,判断是否收到了 “ready” 消息,如果是,就把当前的 input 值发送给 receiver 组件,比如:
ngOnInit(): void {
// 调用服务的方法来接收消息,并传入一个回调函数
this.broadcastService.onMessage((message) => {
// 判断消息的类型是否是 "ready"
if (message.type === 'ready') {
// 如果 input 不为空,就发送一个 "text" 消息
if (this.input) {
this.broadcastService.sendMessage({
type: 'text',
data: this.input
});
}
}
});
}
这样,当你打开 receiver 组件的窗口时,它会向 sender 组件发送一个 “ready” 消息,然后 sender 组件会把当前的 input 值发送给 receiver 组件。你可以试试看效果。😊