为 ngrx/data 实体创建一个选择器
create a selector for a ngrx/data entity
我有一个状态,我想从 ngrx/data 个实体创建 selector。
import {
Action,
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import {environment} from '../../environments/environment';
import * as fromRouter from '@ngrx/router-store';
import * as fromDrawer from './drawer';
import {InjectionToken} from '@angular/core';
import {NavigationItem} from '../models/navigation-item';
export interface State {
router: fromRouter.RouterReducerState<any>;
drawerNavigationItems: fromDrawer.State;
}
export const ROOT_REDUCERS = new InjectionToken<ActionReducerMap<State, Action>>('Root reducers token', {factory: () => ({
router: fromRouter.routerReducer,
drawerNavigationItems: fromDrawer.reducer,
}),
});
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
export const selectRouter = createFeatureSelector<
State,
fromRouter.RouterReducerState<any>
>('router');
const {
selectQueryParams, // select the current route query params
selectQueryParam, // factory function to select a query param
selectRouteParams, // select the current route params
selectRouteParam, // factory function to select a route param
selectRouteData, // select the current route data
selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouter);
export const selectRouteId = selectRouteParam('id');
export const selectStatus = selectQueryParam('status');
// Drawer
export const selectDrawerNavigationItems = (state: State) => state.drawerNavigationItems.items as NavigationItem[];
如何使用预定义的 select 或使用来自 ngrx/data 的实体或服务编写自己的实体或服务?
作为示例,我想创建一个 select 或 select 所有 "Community" 实体,然后,步骤 2,select 1 通过 selectRouteId
。
如果你想象一个路由 /communities/:id
,selectRouteId
是 return 的 Id,现在我想从 CommunityService
获取数据并使用 select 或者创建或者以某种方式导入并在步骤 1 中使用并 return 结果,1 Community
和 selectRouteId
的 id,所以我以后可以做类似 this.store.dispatch(selectCommunityByCurrentRouteId);
[=19= 的事情]
这个问题是针对@ngrx/data的。
您所处情况的最佳解决方案是适配器非常好。
你可以看看这里:https://ngrx.io/guide/entity/adapter
您可以使用它非常轻松地删除、添加、更新商店中的每个对象。
你只需要扩展你的状态 :)
/* src/app/reducers/index.ts */
import * as fromCat from './cat.reducer';
import { Owner } from '~/app/models'
export const ownerSelectors = new EntitySelectorsFactory().create<Owner>('Owner');
export interface State {
cat: fromCat.State;
}
export const reducers: ActionReducerMap<State> = {
cat: fromCat.reducer
};
export const selectCatState = (state: State) => state.cat;
export const {
selectAll: selectAllCats
} = fromCat.adapter.getSelectors(selectCatState);
export const selectedCatsWithOwners = createSelector(
selectAllCats,
ownerSelectors.selectEntities,
(cats, ownerEntities) => cats.map(c => ({
...c,
owner: ownerEntities[c.owner]
}))
);
补充回答,具体回答我自己的问题,
这是 reducers/index.ts 现在的样子
import {
Action,
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import {environment} from '../../environments/environment';
import * as fromRouter from '@ngrx/router-store';
import * as fromDrawer from './drawer';
import {InjectionToken} from '@angular/core';
import {NavigationItem} from '../models/navigation-item';
import {EntitySelectorsFactory} from '@ngrx/data';
import {Community} from '../models/community';
export interface State {
router: fromRouter.RouterReducerState<any>;
drawerNavigationItems: fromDrawer.State;
}
export const ROOT_REDUCERS = new InjectionToken<ActionReducerMap<State, Action>>('Root reducers token', {factory: () => ({
router: fromRouter.routerReducer,
drawerNavigationItems: fromDrawer.reducer,
}),
});
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
export const selectRouter = createFeatureSelector<
State,
fromRouter.RouterReducerState<any>
>('router');
const {
selectQueryParams, // select the current route query params
selectQueryParam, // factory function to select a query param
selectRouteParams, // select the current route params
selectRouteParam, // factory function to select a route param
selectRouteData, // select the current route data
selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouter);
export const selectRouteId = selectRouteParam('id');
// export const selectStatus = selectQueryParam('status');
// Data
export const communitySelectors = new EntitySelectorsFactory().create<Community>('Community');
export const selectCommunityByRouteId = createSelector(
selectRouteId,
communitySelectors.selectEntities,
(id, communities) => communities.find(c => c.id === id)
);
// Drawer
export const selectDrawerNavigationItems = (state: State) => state.drawerNavigationItems.items as NavigationItem[];
您使用
为社区模型创建了一个选择器
export const communitySelectors = new EntitySelectorsFactory().create<Community>('Community');
然后你将这两个和 return 1 Community
通过路线 id 结合起来。
export const selectCommunityByRouteId = createSelector(
selectRouteId,
communitySelectors.selectEntities,
(id, communities) => communities.find(c => c.id === id)
);
非常简单,您选择输入流,提供投影函数和 return 结果。
稍后,在组件中
export class OneCommunityComponent implements OnInit {
community$: Observable<Community>;
constructor(
private store: Store<State>,
) {
this.community$ = this.store.select(selectCommunityByRouteId);
}
}
我有一个状态,我想从 ngrx/data 个实体创建 selector。
import {
Action,
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import {environment} from '../../environments/environment';
import * as fromRouter from '@ngrx/router-store';
import * as fromDrawer from './drawer';
import {InjectionToken} from '@angular/core';
import {NavigationItem} from '../models/navigation-item';
export interface State {
router: fromRouter.RouterReducerState<any>;
drawerNavigationItems: fromDrawer.State;
}
export const ROOT_REDUCERS = new InjectionToken<ActionReducerMap<State, Action>>('Root reducers token', {factory: () => ({
router: fromRouter.routerReducer,
drawerNavigationItems: fromDrawer.reducer,
}),
});
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
export const selectRouter = createFeatureSelector<
State,
fromRouter.RouterReducerState<any>
>('router');
const {
selectQueryParams, // select the current route query params
selectQueryParam, // factory function to select a query param
selectRouteParams, // select the current route params
selectRouteParam, // factory function to select a route param
selectRouteData, // select the current route data
selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouter);
export const selectRouteId = selectRouteParam('id');
export const selectStatus = selectQueryParam('status');
// Drawer
export const selectDrawerNavigationItems = (state: State) => state.drawerNavigationItems.items as NavigationItem[];
如何使用预定义的 select 或使用来自 ngrx/data 的实体或服务编写自己的实体或服务?
作为示例,我想创建一个 select 或 select 所有 "Community" 实体,然后,步骤 2,select 1 通过 selectRouteId
。
如果你想象一个路由 /communities/:id
,selectRouteId
是 return 的 Id,现在我想从 CommunityService
获取数据并使用 select 或者创建或者以某种方式导入并在步骤 1 中使用并 return 结果,1 Community
和 selectRouteId
的 id,所以我以后可以做类似 this.store.dispatch(selectCommunityByCurrentRouteId);
[=19= 的事情]
这个问题是针对@ngrx/data的。
您所处情况的最佳解决方案是适配器非常好。 你可以看看这里:https://ngrx.io/guide/entity/adapter
您可以使用它非常轻松地删除、添加、更新商店中的每个对象。 你只需要扩展你的状态 :)
/* src/app/reducers/index.ts */
import * as fromCat from './cat.reducer';
import { Owner } from '~/app/models'
export const ownerSelectors = new EntitySelectorsFactory().create<Owner>('Owner');
export interface State {
cat: fromCat.State;
}
export const reducers: ActionReducerMap<State> = {
cat: fromCat.reducer
};
export const selectCatState = (state: State) => state.cat;
export const {
selectAll: selectAllCats
} = fromCat.adapter.getSelectors(selectCatState);
export const selectedCatsWithOwners = createSelector(
selectAllCats,
ownerSelectors.selectEntities,
(cats, ownerEntities) => cats.map(c => ({
...c,
owner: ownerEntities[c.owner]
}))
);
补充回答,具体回答我自己的问题, 这是 reducers/index.ts 现在的样子
import {
Action,
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import {environment} from '../../environments/environment';
import * as fromRouter from '@ngrx/router-store';
import * as fromDrawer from './drawer';
import {InjectionToken} from '@angular/core';
import {NavigationItem} from '../models/navigation-item';
import {EntitySelectorsFactory} from '@ngrx/data';
import {Community} from '../models/community';
export interface State {
router: fromRouter.RouterReducerState<any>;
drawerNavigationItems: fromDrawer.State;
}
export const ROOT_REDUCERS = new InjectionToken<ActionReducerMap<State, Action>>('Root reducers token', {factory: () => ({
router: fromRouter.routerReducer,
drawerNavigationItems: fromDrawer.reducer,
}),
});
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
export const selectRouter = createFeatureSelector<
State,
fromRouter.RouterReducerState<any>
>('router');
const {
selectQueryParams, // select the current route query params
selectQueryParam, // factory function to select a query param
selectRouteParams, // select the current route params
selectRouteParam, // factory function to select a route param
selectRouteData, // select the current route data
selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouter);
export const selectRouteId = selectRouteParam('id');
// export const selectStatus = selectQueryParam('status');
// Data
export const communitySelectors = new EntitySelectorsFactory().create<Community>('Community');
export const selectCommunityByRouteId = createSelector(
selectRouteId,
communitySelectors.selectEntities,
(id, communities) => communities.find(c => c.id === id)
);
// Drawer
export const selectDrawerNavigationItems = (state: State) => state.drawerNavigationItems.items as NavigationItem[];
您使用
为社区模型创建了一个选择器export const communitySelectors = new EntitySelectorsFactory().create<Community>('Community');
然后你将这两个和 return 1 Community
通过路线 id 结合起来。
export const selectCommunityByRouteId = createSelector(
selectRouteId,
communitySelectors.selectEntities,
(id, communities) => communities.find(c => c.id === id)
);
非常简单,您选择输入流,提供投影函数和 return 结果。
稍后,在组件中
export class OneCommunityComponent implements OnInit {
community$: Observable<Community>;
constructor(
private store: Store<State>,
) {
this.community$ = this.store.select(selectCommunityByRouteId);
}
}