*ngIf 与从 BehaviorSubject 观察到的异步管道似乎激活不正确,直到加载数据
*ngIf with async pipe for observable from BehaviorSubject seem to activate incorrectly until data is loaded
如果响应中的数组为空我想显示一条消息,否则为数组的元素。
如果响应有一个非空数组,*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();
}
...
}
如果我直接调用组件中的服务(而不是商店),它会按预期运行...
您应该通过将局部变量分配为
来重组模板以有效处理异步调用
<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
罪魁祸首是使用 empty 列表初始化 BehaviorSubject,它被发出并且条件评估为真:
private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(List([]));
修复 - 使用 null
或 undefined
初始化 BehaviorSubject
private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(null);
如果响应中的数组为空我想显示一条消息,否则为数组的元素。
如果响应有一个非空数组,*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();
}
...
}
如果我直接调用组件中的服务(而不是商店),它会按预期运行...
您应该通过将局部变量分配为
来重组模板以有效处理异步调用<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
罪魁祸首是使用 empty 列表初始化 BehaviorSubject,它被发出并且条件评估为真:
private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(List([]));
修复 - 使用 null
或 undefined
private _personalBookmarks: BehaviorSubject<List<Bookmark>> = new BehaviorSubject(null);