[英]Angular: check if Observable / BehaviorSubject has relevant changes
我有一個用戶 object 我在會員服務中觀察到。
只有當用戶 object 有相關更改時,我才想更新我的服務。
為了了解我的用戶 object 是否有相關變化,我將我的本地用戶 object 與觀察到的用戶進行了比較。 然后總是分配新的 object。
但是,這不起作用。
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));
}
}
為什么我的 function hasUserRelevantChanges()
總是比較相同的新對象? 本地this.user
始終在此檢查中保存新值,即使分配this.user = user
之后出現?
那么,與舊/以前的用戶對象相比,我的新user
object 的相關值是否發生了變化,我該如何理解呢?
提前致謝!
“為什么我的 function hasUserRelevantChanges()
總是比較相同的新對象?”
那是因為您總是將新值分配給this.user
變量。 理想情況下,只有當它不同時,您才需要使用新user
對其進行更新。 換句話說,它必須在if
塊內移動。
this.subscription = this.auth.user$.subscribe((user) => {
const updateServices = this.hasUserRelevantChanges(user)
if (updateServices) {
this.user = user;
this.updateMyServices();
}
});
在您的場景中,您最好使用 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((user) =>
this.updateMyServices();
);
使用RxJs
運算符來執行此操作。 您不需要將 user 存儲在代碼中的某個位置,但您可以使用pairwise
和filter
pipe
它。 所以它會是這樣的:
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 arguments。
Edit3:為什么你的代碼不起作用? 因為Object.assign
不會創建新的 object 參考,而是更改原始 object - 所以實際上,您每次都在檢查相同的 ZA8CFDE63131ACBD59
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.