* ng如果具有从BehaviorSubject可观察到的异步管道,则似乎无法正确激活,直到加载数据

时间:2019-04-21 20:51:15

标签: angular rxjs observable behaviorsubject

如果响应的数组为空,我想显示一条消息,否则显示数组的元素。

如果响应具有非空数组,则 * ngIf 条件的评估结果为 true ,并且消息显示为直到加载。

HTML模板代码段:

<div *ngIf="personalAndStarredBookmarks$ && (personalAndStarredBookmarks$ | async)?.size === 0; else personalBookmarksList" class="missing-category-bookmarks-message  alert alert-info">
  <p>No bookmarks yet</p>
</div>
<ng-template #personalBookmarksList>
  <app-async-bookmark-list [bookmarks]="personalAndStarredBookmarks$" [shownSize]="10" [userData]="userData"></app-async-bookmark-list>
</ng-template>

组件片段:

import { List } from 'immutable';

export class PersonalBookmarksListComponent implements OnInit {

  personalAndStarredBookmarks$: Observable<List<Bookmark>>;

  ngOnInit(): void {

    this.personalAndStarredBookmarks$ = this.personalBookmarksStore.getPersonalBookmarks();
  }
  ...
}

商店使用 BehaviourSubject 来保存实际执行HTTP调用的服务的响应。

商店摘要

@Injectable()
export class PersonalBookmarksStore {

  private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(List([]));

  constructor(private personalBookmarkService: PersonalBookmarkService,
              private keycloakService: KeycloakService
  ) {
    keycloakService.loadUserProfile().then(keycloakProfile => {
      this.userId = keycloakProfile.id;
      this.loadInitialData();
    });
  }

  private loadInitialData() {
    this.personalBookmarkService.getAllPersonalBookmarks(this.userId)
      .subscribe(
        data => {
          let bookmarks: Bookmark[] = <Bookmark[]>data;
          this._personalBookmarks.next(List(bookmarks));
        },
        err => console.error('Error retrieving bookmarks', err)
      );
  }

  getPersonalBookmarks(): Observable<List<Bookmark>> {
    return this._personalBookmarks.asObservable();
  }
  ...
}

如果我直接在组件中调用服务(而不是商店),则其行为符合预期...

2 个答案:

答案 0 :(得分:0)

您应该通过将本地变量分配为

来重组模板,以有效地处理异步调用
<ng-content*ngIf="personalAndStarredBookmarks$ | async as personalAndStarredBookmarks">
    <div *ngIf="personalAndStarredBookmarks.size === 0; else personalBookmarksList" 
        class="missing-category-bookmarks-message  alert alert-info">
        <p>No bookmarks yet</p>
    </div>
    <ng-template #personalBookmarksList>
        <app-async-bookmark-list [bookmarks]="personalAndStarredBookmarks" [shownSize]="10"
            [userData]="userData">
        </app-async-bookmark-list>
    </ng-template>
<ng-content>

这样,您可以有效地处理所有条件,并且只有在异步调用解决后,主要内容才会加载。

查看DEMO HERE

答案 1 :(得分:0)

罪魁祸首是带有列表的BehaviorSubject的初始化,该列表被发出并且条件评估为true:

private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(List([]));

修复-使用nullundefined

初始化BehaviorSubject
private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(null);