use*_*244 2 ngrx ngrx-effects angular
@Component({
selector: 'app-user',
styleUrls: ['./user.component.css'],
template: `
<button (click)="clickSearch('some keyword')">Search</button>
<div *ngIf="books$ | async as books">
<h5 *ngIf="hasSearched">No. of books: {{ books.length }}</h5>
<p *ngIf="hasSearched && !books.length">No books found</p>
<p *ngIf="!hasSearched">Please enter a search keyword to start searching for books.</p>
<h2 *ngFor="let book of books">{{ book.title }}</h2>
</div>
`
})
export class UserComponent {
constructor(private store: Store) {}
hasSearched: boolean = false;
books$ = this.store.select(BooksSelector.getBooks)
.pipe(
tap(data => console.log(data))
);
clickSearch(keyword: string) {
this.hasSearched = true;
this.store.dispatch(BooksActions.loadBooksFromApi(
{ q: keyword }
));
}
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个简化的 Angular 组件代码,如上所示。流程:
当我们第一次到达此页面时,store.select() 语句立即从 store 返回初始状态值[]。这将导致模板显示“未找到书籍”和“书籍数量=0”消息,这是我不想要的。因此,为了防止这种情况,我添加了hasSearched布尔属性并显示“请输入...”消息。
单击“搜索”按钮后,该hasSearched属性将变为true,并且当 API 检索数据时,模板将短暂显示“未找到书籍”和“书籍数量=0”消息。我不希望它这样做。我希望消息能够等待(通过隐藏)直到 API 调用完成。
API调用完成后,书籍列表正常显示在模板中,并且消息正确显示。
当用户搜索完某些内容并获得一些结果,然后离开页面并返回页面后,store.select() 语句将返回之前的存储值。我不想要这个。我只是希望此页面重新开始,没有书籍列表,只有消息“请输入搜索关键字以开始搜索书籍。”。
我的问题是针对第 2 点和第 4 点:
对于第 2 点,我应该添加另一个布尔属性来检查加载状态吗?似乎 *ngIf 标志太多。有没有更优雅的方法通过 NgRx 选择器来处理这个问题?
对于第 4 点,我如何实现这一目标?是通过[]在 store 中推入一个空来ngOnDestroy()强制清除 Books 状态吗?
对于点号 2
我建议hasSearched: boolean在您的减速器中添加另一个布尔值,然后hasSearched从组件中删除。订阅hasSearched在组件中使用选择器。当用户第一次输入该组件时,应该是undefined。由此,您可以显示您的消息
<p *ngIf="(hasSearched | async) === undefined">
Please enter a search keyword to start searching for books.
</p>
Run Code Online (Sandbox Code Playgroud)
当用户单击按钮时,您将调度您的操作BooksActions.loadBooksFromApi。false在同一操作/减速器中,当 API 调用正在进行时,将字段 hasSearched 转换为,此false标志将阻止显示这两条消息:
<h5 *ngIf="(hasSearched | async)">No. of books: {{ books.length }}</h5>
<p *ngIf="(hasSearched | async) && !books.length">No books found</p>
Run Code Online (Sandbox Code Playgroud)
直到true完成为止。作为参考,您的状态和减速器将如下所示。
export interface BooksState {
books: any;
hasSearched: boolean;
}
export const initialState: BooksState = {
books: undefined,
hasSearched: undefined
};
Run Code Online (Sandbox Code Playgroud)
减速器的情况看起来像这样。
case BooksActionsTypes.loadBooksFromApi:
return {
...state,
hasSearched: false
};
case BooksActionsTypes.loadBooksFromApiSuccessful:
return {
...state,
books: action.payload.books
hasSearched: true
};
Run Code Online (Sandbox Code Playgroud)
对于点 4
根据我的理解,您的想法是正确的,通过在 上发送操作来清除状态ngOnDestroy()。这与我使用的方式相同,当我想在下次访问同一组件时获得新的状态时,可以清除状态。这将类似于我在下面写的内容
case BooksActionsTypes.ClearState:
return {
...state,
books: undefined
hasSearched: undefined
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
689 次 |
| 最近记录: |