行为主题只有在有新事物的情况下才返回

发布于 2025-02-03 05:16:21 字数 836 浏览 3 评论 0原文

我有以下问题,当我调用getstudentslist函数时,它将转到服务器以查找所需的新值,但是行为主题再次返回当前值(这会导致我问题,因为它加载了视图,将视图加载到先前的值中)当我等待服务器信息返回时。 我该如何避免这种行为?

  getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    return this.studentListSubject$.asObservable().pipe(filter((value) => value !== null));
  }

  refetchStudentList(gridParams) {
    const subscription = this.http.post<StudentListGrid>(this.baseUrl + 'GetStudents', {gridParams} ,httpOptions).pipe(map(data => this.setDefaultValuesToStudent(data))).subscribe(
      (response) => {

        this.studentListSubject$.next(response);
        subscription.unsubscribe();
      });
  }

I have the following problem, when I call the getStudentsList function, it goes to the server to find the new values that I need, but the behaviorSubject returns the current value again (This causes me problems because it load the view with the previous values) while I wait for the server information to return.
How can I do to avoid this behavior?

  getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    return this.studentListSubject$.asObservable().pipe(filter((value) => value !== null));
  }

  refetchStudentList(gridParams) {
    const subscription = this.http.post<StudentListGrid>(this.baseUrl + 'GetStudents', {gridParams} ,httpOptions).pipe(map(data => this.setDefaultValuesToStudent(data))).subscribe(
      (response) => {

        this.studentListSubject$.next(response);
        subscription.unsubscribe();
      });
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漫雪独思 2025-02-10 05:16:21

基于

行为主题:
主题的变体需要初始值,并在订阅

时发出其当前值

解决方案1

以进行快速解决方案时发出其当前值,您可以在 getSudentslistlist 函数中返回可观察到的null。

  getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    // add this line
    this.studentListSubject$.next(null);
    return this.studentListSubject$.asObservable().pipe(filter((value) => value !== null));
  }

中 通过null通过null来清空行为的最后一个值,因此此函数的返回始终返回新的值。

解决方案2

另一种方法(更好的方法)是使用rxjs库中的不同的企业,我想您的名字在每个响应中都会有所不同:

 getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    return this.studentListSubject$.asObservable().pipe(
             filter((value) => value !== null),
             distinctUntilChanged((prev, curr) => prev.name === curr.name));
  }

希望此答案对您有所帮助。

Based on the definition of BehaviorSubject from doc

BehaviorSubject:
A variant of Subject that requires an initial value and emits its current value whenever it is subscribed to

Solution 1

For a quick solution, you can set null before you return Observable in the getStudentsList function:

  getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    // add this line
    this.studentListSubject$.next(null);
    return this.studentListSubject$.asObservable().pipe(filter((value) => value !== null));
  }

The reason is you empty the last value of BehaviorSubject by passing null so the return of this function always returns a fresh value.

Solution 2

Another way (better way) is to use distinctUntilChanged from RxJs library, I suppose your name become different in each response:

 getStudentsList(params): Observable<StudentsListGrid> {
    if (this.studentListSubject$ === undefined) {
      this.studentListSubject$ = new BehaviorSubject<StudentListGrid>(null);
    }
    this.refetchStudentList(params);
    return this.studentListSubject$.asObservable().pipe(
             filter((value) => value !== null),
             distinctUntilChanged((prev, curr) => prev.name === curr.name));
  }

I hope this answer helps you.

慕巷 2025-02-10 05:16:21

通常,您不想为了更新另一个可观察到的主题而订阅某些东西。取而代之的是结局的连锁事件。

private studentListTrigger$ = new Subject();

readonly studentList$ = concat(
  of(null), // triggers a refresh the first time something subscribes to studentList$
  this.studentListTrigger$
).pipe(
  switchMap( // if a new request, drop any previous request in progress.
    () => this.http.post<StudentListGrid>(
      this.baseUrl + 'GetStudents',
      {gridParams},
      httpOptions
    ).pipe(
      catchError(() => EMPTY) // don't let the error of any given attempt break studentList$
    )
  ),
  filter((value) => value !== null),
  shareReplay(1) // No matter how many subscribers, as long as there's at least one subscriber, do all of the above exactly once and then emit the last value to any late subscribers just like a BehaviorSubject does
);

refreshStudentList(): void {
  this.studentListTrigger$.next();
}

现在,无论消耗学生列表$什么都将获得最后的结果,并在每次刷新时都会收到新的学生列表。

As a rule, you do not want to subscribe to something for the purposes of updating another observable or subject. Instead, chain events to outcomes.

private studentListTrigger$ = new Subject();

readonly studentList$ = concat(
  of(null), // triggers a refresh the first time something subscribes to studentList$
  this.studentListTrigger$
).pipe(
  switchMap( // if a new request, drop any previous request in progress.
    () => this.http.post<StudentListGrid>(
      this.baseUrl + 'GetStudents',
      {gridParams},
      httpOptions
    ).pipe(
      catchError(() => EMPTY) // don't let the error of any given attempt break studentList$
    )
  ),
  filter((value) => value !== null),
  shareReplay(1) // No matter how many subscribers, as long as there's at least one subscriber, do all of the above exactly once and then emit the last value to any late subscribers just like a BehaviorSubject does
);

refreshStudentList(): void {
  this.studentListTrigger$.next();
}

Now, whatever consumes studentList$ will receive the last-emitted result, plus a new student list every time it's refreshed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文