簡體   English   中英

Angular:檢查 Observable / BehaviorSubject 是否有相關變化

[英]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 存儲在代碼中的某個位置,但您可以使用pairwisefilter 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM