angular - 什么决定了 Socket IO 的 Angular 区域
问题描述
我在 Angular 服务中使用 SocketIO 时遇到了一个有趣的问题。
案例 1:作为服务属性的
套接字当我在服务类上实例化套接字时,来自套接字的所有响应都在角度区域中完成,并且 UI 将相应地更新。
import { io } from 'socket.io-client/build/index';
import { Injectable, NgZone } from '@angular/core';
@Injectable() {
export class MyService {
private socket = io("localhost:3000")
dealCards(): void {
this.socket.emit('deal_cards')
}
recieveStartingCards(): Observable<GameState> {
const observable = new Observable<GameState>((observer) => {
this.socket.on('dealt_cards', (data: GameState) => {
console.log('IN ZONE', NgZone.isInAngularZone()); // returns true
observer.next(data));
return () => this.socket.disconnect();
});
});
return observable;
}
案例 2:作为常量
的套接字当我将套接字实例化为常量并在服务类中引用它时。套接字通信发生在角度区域之外,UI 只会在您使用时更新ngZone.run()
import { io } from 'socket.io-client/build/index';
import { Injectable, NgZone } from '@angular/core';
const socket = io("localhost:3000")
@Injectable() {
export class MyService {
constructor(private ngZone: NgZone) {}
private socket = socket
dealCards(): void {
this.socket.emit('deal_cards')
}
recieveStartingCards(): Observable<GameState> {
const observable = new Observable<GameState>((observer) => {
this.socket.on('dealt_cards', (data: GameState) => {
console.log('IN ZONE', NgZone.isInAngularZone()); // returns false
observer.next(data));
return () => this.socket.disconnect();
});
});
return observable;
}
我的问题是为什么案例 1 中的套接字通信总是在角度区域中,为什么案例 2 中的套接字通信从不在角度区域中?
解决方案
Angular zone 在引导Angular 应用程序的阶段开始发挥作用。DI(依赖注入)系统中涉及的所有 Angular 服务都在此NgZone.run
调用中实例化。
在第一种情况下,您使用套接字作为属性。这意味着它将在服务构造函数中实例化,并且在引导过程之后发生。
在第二种情况下,io
当没有定义 Angular 区域时,您在引导应用程序之前进行初始化。
推荐阅读
- android-volley - 数组没有被填充。列表视图也没有填充。数组大小多于一个但只有一个值打印
- javascript - Async/Await 在被调用函数完成之前返回未定义
- java - 如何通过url获取分页中的所有数据
- python - 如何在scrapy中发出请求以避免硒中间件?
- postgresql - 当对 TABLE1 进行 SELECT 查询时,如何创建将 TABLE1 的值插入到 TABLE2 的规则
- php - 如何通过最佳实践将 OpenCart 设置到 Heroku
- c# - 每个 Grpc 一元调用的 C# 重用或创建新客户端
- ssis - 我们可以在 SSIS SMTP 邮件任务中进行用户名和密码验证吗?
- python - 为多个类创建图像数据集
- c# - 需要修改导航方法以使导航多于一个