我有一个可以正常使用的平台,该平台在服务中使用Rxjs行为主题(Observables)来保持整个应用程序的状态。在我需要包括WebSocket来更新同一帐户中许多用户的信息之前,它的运行情况还不错。 当更新的信息到达用户时,我称行为为对象,以检查是否应该更新活动的供应商(用户当前正在查看的供应商),但是Observable始终返回“ null”,因为它是该供应商的新实例。可观察到的(与用户屏幕上显示的不一样)。
为了测试它,我在两个不同的文件中记录了相同的可观察值:
// Supplier.service.ts
import { Injectable } from "@angular/core";
import { BehaviorSubject } from 'rxjs';
import { Supplier } from '../../models/supplier.model';
import { UserService } from './User.service';
@Injectable({providedIn: 'root'})
export class SupplierService {
activeSupplier = new BehaviorSubject<Supplier>(null);
constructor (
private http: HttpClient,
private userService: UserService,
) {}
{...}
getOneSupplier(supplierId: string) {
this.http.get<Supplier>(`${BASEURL}supplier/${supplierId}`)
.subscribe(supplier => {
this.activeSupplier.next(supplier);
this.activeSupplier.pipe(take(1)).subscribe(activeSupplier => {
console.log('updater:', activeSupplier); // <----------------- here
});
});
}
updateSupplierList(changedSupplier) {
this.activeSupplier.pipe(take(1)).subscribe(activeSupplier => {
console.log('Socket changing active supplier:', activeSupplier);
if (activeSupplier._id === changedSupplier._id) {
this.getOneSupplier(activeSupplier._id);
}
});
}
{...}
}
// Socket.service.js
import { Injectable } from '@angular/core';
import io from './SocketCopier.js';
import { UserService } from './User.service.js';
import { SupplierService } from './Supplier.service.js';
@Injectable({
providedIn: 'root',
})
export class SocketService {
socket;
subs = {};
constructor(
private userService: UserService,
private supplierService: SupplierService
) {
this.supplierService.activeSupplier.subscribe(activeSupplier => {
console.log('socket:', activeSupplier); // <----------------- and here
});
}
loadSocket(user) {
io.then((result) => {
if (this.socket) {
this.socket.close();
}
this.socket = result('http://localhost:3000');
this.socket.on('connect', () => {
this.socket.emit('login', { account: user.account._id })
});
this.socket.on('logged', (msg) => {
console.log(msg.text);
});
this.socket.on('supplierChange', (msg) => {
this.supplierService.updateSupplierList(msg.data);
});
});
}
}
// supplier-info.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { SupplierService } from 'src/app/shared/services/Supplier.service';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Supplier } from 'src/app/models/supplier.model';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-supplier-info',
templateUrl: './supplier-info.component.html',
styleUrls: ['./supplier-info.component.css'],
})
export class SupplierInfoComponent implements OnInit, OnDestroy {
supplier: Supplier;
subs = {};
activeRoute: string = 'projetos';
constructor(
private supplierService: SupplierService,
private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit() {
this.supplierService.getOneSupplier(this.route.snapshot.params.supplierId);
}
{...}
}
代码首先调用Socket.service.ts,后者调用Supplier.service.ts,后者创建行为主体“ activeSupplier”,初始值为“ null”。
然后,Socket.service.ts在其构造函数中订阅可观察到的“ activeSupplier”并按预期返回“ null”。
然后生成了vendor-info.component.ts,并在ngOnInit中要求提供供应商信息,调用“ this.supplierService.getOneSupplier()”。这将更新记录供应商的“ activeSupplier” BehaviorSubject。
这是我从这些日志中得到的结果:
socket: null
updater: {socialMediaUrls: {…}, photoUrl: "", emails: Array(0), skills: Array(0), tags: Array(4), …}
套接字的observable不会再更新,因为它是“ supplierService”的新实例,并且不与Supplier-info.component.ts共享相同的“ activeSupplier”。应该更新吧?由于它订阅了相同的Observable(至少在理论上是这样)。
我在这里没看到什么? 预先感谢您的所有帮助!
编辑: 值得一提的是,任何对“ activeSupplier”和“ Observable”订阅的新订阅都将返回“ null”,因为它是第一个值(即使在第二个console.log和供应商之后)。
答案 0 :(得分:0)
阅读注释和其中的代码,我想您可以尝试这样的事情。
首先,您可能会将一开始从http服务获得的有效供应商的价值保存在某个地方。像这样
export class SupplierService {
activeSupplier = new BehaviorSubject<Supplier>(null);
activeSupplierValue: Supplier;
constructor (
private http: HttpClient,
private userService: UserService,
) {}
...
getOneSupplier(supplierId: string) {
this.http.get<Supplier>(`${BASEURL}supplier/${supplierId}`)
.subscribe(supplier => {
this.activeSupplierValue = supplier; // save the data of the active supplier
......
});
});
}
...
}
然后,将有效供应商与从套接字收到的任何内容进行比较,如果匹配,则再次触发getOneSupplier
。
updateSupplierList(changedSupplier) {
if (activeSupplier._id === changedSupplier._id) {
this.getOneSupplier(activeSupplier._id);
}
}
答案 1 :(得分:0)
我找到了! 经过许多(MANY)调试日志后,我发现我确实在创建该服务的另一个实例。为了找到答案,我登录了Supplier.service.ts构造函数。然后,我看到两个日志都发生在不同的行中。打开这些文件(chrome inspect>源代码),我看到它们是不同的(?),所以我尝试“重写” Sockets.service.ts中的导入,并且可以正常工作!
那是因为我错误地导入了它(末尾带有'.js')。
从此:
import { UserService } from './User.service.js';
import { SupplierService } from './Supplier.service.js';
对此:
import { UserService } from './User.service';
import { SupplierService } from './Supplier.service';
现在一切正常!