我有一個在會員服務中觀察到的用戶物件。
只有當用戶物件有相關更改時,我才想更新我的服務。
為了了解我的用戶物件是否有相關更改,我將本地用戶物件與觀察到的用戶物件進行了比較。然后總是分配新物件。
然而,這不起作用。
export class MemberService {
private subscription?: Subscription;
user?: User;
constructor(public auth: AuthService) {
this.subscription = this.auth.user$.subscribe((user) => {
const updateServices = this.hasUserRelevantChanges(user)
// apparently this line always fires before the functioncall above?!
this.user = user;
if (updateServices) {
this.updateMyServices();
}
});
}
ngOnDestroy() {
this.subscription?.unsubscribe();
}
hasUserRelevantChanges(user: User | undefined): boolean {
return user?.subscription !== this.user?.subscription ||
user?.username !== this.user?.username ||
user?.isBanned !== this.user?.isBanned;
}
updateMyServices(): void {
// Updating my services!!!
}
}
export class AuthService {
public readonly user$: Observable<User| undefined> = this.user.asObservable();
user: BehaviorSubject<User| undefined> = new BehaviorSubject<User| undefined>(undefined);
constructor(private httpHandler: HttpHandlerService) { ... }
handleUser(): void {
this.httpHandler.login().subscribe(
(user: User) => this.user.next(user));
}
updateUserData(newUser: User): void {
this.user.next(Object.assign(this.user.value, newUser));
}
}
為什么我的函式hasUserRelevantChanges()總是比較相同的新物件?本地this.user總是在此檢查中保留新值,即使分配this.user = user是在之后進行的?
那么user,與舊的/以前的用戶物件相比,我如何理解我的新物件的相關值是否發生了變化?
提前致謝!
uj5u.com熱心網友回復:
使用RxJs運算子來執行此操作。您不需要在代碼中的某處存盤用戶,但您可以pipe使用pairwise和filter。所以它會是這樣的:
this.auth.user$.pipe(
pairwise(),
filter(users => userChanged(users[0], users[1]))
... // other operators to handle change - tap, map etc
)
如果您將邏輯移至適當的運算子,它會更清晰。
編輯:Pairwise回傳兩個值:previous 和 current,filter- 顧名思義,過濾事件并僅在傳遞的回呼回傳 true 時才發出 next
Edit2:您應該實作userChanged或調整您hasUserRelevantChanges現在需要傳遞 2 個引數的內容。
Edit3:為什么你的代碼不起作用?因為Object.assign不會創建新的物件參考而是更改原始物件 - 所以實際上,您每次都在檢查同一個物件。
更新:傳播運算子:
updateUserData(newUser: User): void {
this.user.next({...this.user.value, ...newUser});
}
uj5u.com熱心網友回復:
“為什么我的函式hasUserRelevantChanges()總是比較相同的新物件?”
那是因為您總是將新值分配給this.user變數。理想情況下,user 只有當它不同時才需要用新的更新它。換句話說,它必須在if塊內移動。
this.subscription = this.auth.user$.subscribe((user) => {
const updateServices = this.hasUserRelevantChanges(user)
if (updateServices) {
this.user = user;
this.updateMyServices();
}
});
更新:pairwise filter
在您的場景中,您最好使用 RxJS pairwise filter運算子來檢查條件。
this.subscription = this.auth.user$.pipe(
pairwise(),
filter(([user1, user2]) => (
user1?.subscription !== user2?.subscription ||
user1?.username !== user2?.username ||
user1?.isBanned !== user2?.isBanned;
))
).subscribe(([user1, user2]) => { // <-- Update 2: ignore `user1`
this.updateMyServices(user2);
);
如果您實際上是將物件的所有屬性與其以前的值進行比較,則可以將整個pairwise filter替換為distinctUntilChanged運算子。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/362682.html
上一篇:Angular/Typescript/RxJs:在觀察變化的同時更新BehaviorSubject(物件分配)的值
