我有一个博客应用程序,我正在使用ngrx。
应用程序-for现在-在存储中有两个对象
{
"posts": [...],
"users": [...]
}现在,我想创建一个分离的组件来显示单个post (所选的-post.Component)。
我试图使用这样的选择器通过实体的id来选择该实体:
export const selectPostById = (id: string) => createSelector(
selectEntities,
entities => entities[id]
);然后将其放入组件中:
postId: string = localStorage.getItem("_selectedPostId");
selectedPost: Observable<Post> = this.store.select(selectPostById(postId));然后,为了在视图中显示它,我使用:
<ng-container *ngIf="selectedPost | async">
<div class="post text-light">
<div class="p-title fs-3">{{(selectedPost | async).title}}</div>
<div class="p-image">
<img [src]="(selectedPost | async).imageSrc">
</div>
<div class="p-cont fs-5">
{{(selectedPost | async).content}}
</div>
<div class="p-category float-start fs-6">
<a class="p-1" href="categories/category" *ngFor="let ct of (selectedPost | async).categories">
{{ct}}
</a>
</div>
<div class="p-date float-end fs-6">
{{(selectedPost | async).date}}
</div>
<div class="p-author fs-6">
<a href="users/otheruser">{{(selectedPost | async).author.name}}</a>
</div>
</div>
<div class="info">Comments</div>
<div class="comments text-light">
<div class="comment border rounded m-1" *ngFor="let comment of (selectedPost | async).comments">
<div class="c-author">
<a href="users/otheruser">{{comment.author.name}}</a>
</div>
<div class="c-cont">{{comment.content}}</div>
<div class="-c-date">{{comment.date}}</div>
<div class="replies" *ngIf="comment.replies">
<div class="comment border rounded m-1" *ngFor="let reply of comment.replies">
<div class="c-author">
<a href="users/otheruser">{{reply.author.name}}</a>
</div>
<div class="c-cont">{{reply.content}}</div>
<div class="c-date">{{reply.date}}</div>
</div>
</div>
</div>
</div>
</ng-container>因此,问题是在控制台中没有显示带有错误的post:
ERROR TypeError: Cannot read properties of undefined (reading: '1')
我选择了id "1“的post,它存在于显示的状态中。
有什么主意吗?
编辑:减速机:
import { Action, createFeatureSelector, createReducer, createSelector, on } from '@ngrx/store';
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
import * as postActions from './actions';
import { Post } from 'src/app/models/post';
export interface PostState extends EntityState<Post> {
error: any;
selectedPostId: string | null;
}
export function selectUserId(a: Post): string {
return a.id;
}
export const adapter: EntityAdapter<Post> = createEntityAdapter<Post>({
selectId: selectUserId,
sortComparer: false
});
export const initialState = adapter.getInitialState({error: null,selectedPostId: null});
const testsReducer = createReducer(
initialState,
on(postActions.loadPostsSuccess, (state, {posts}) => adapter.setAll(posts, state)),
on(postActions.loadPostsFailed, (state, {error}) => ({...state, error})),
on(postActions.setSelectedPostId, (state, {id}) => ({...state, selectedPostId: id}))
);
export function reducer(state: PostState, action: Action) {
return testsReducer(state, action);
}
// Selectors
const {
selectIds,
selectEntities,
selectAll,
selectTotal,
} = adapter.getSelectors();
const feature = createFeatureSelector<PostState>('posts');
export const getPosts = createSelector(feature,selectAll);
export const getSelectedPostId = (state: PostState) => state.selectedPostId;
export const selectPostId = createSelector(
feature,
getSelectedPostId
);
export const selectPostById = (id: string) => createSelector(
selectEntities,
entities => entities[id]
);发布于 2022-02-27 19:04:10
您必须将selectEntities选择器从适配器链接到feature one (由createFeatureSelector函数创建),然后使用它通过Id获取所需的实体。
您可以尝试以下方法:
// Selectors
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();
const feature = createFeatureSelector<PostState>('posts');
// ...
// Create a selector from the feature selector and selectEntities one.
export const selectPostEntities = createSelector(feature, selectEntities);
// Use the new selector `selectPostEntities` to slice the post entity from it.
export const selectPostById = (id: number) =>
createSelector(selectPostEntities, (entities) => entities[id]);此外,您还可以通过只使用selectedPost管道一次订阅可观察到的asyn来优化组件模板,如下所示:
<ng-container *ngIf="selectedPost | async as _selectedPost">
<!-- You can now use the `_selectedPost` variable without `async` pipe for all the elements inside the ng-container -->
</ng-container>https://stackoverflow.com/questions/71287456
复制相似问题