我最近一直在研究ngrx和redux模式,我在想如何将现有的Angular2应用程序重写为使用ngrx / store。 我所拥有的是一个应用程序,用户可以查看和(如果已登录)可以喜欢和发布引文。 典型的引用对象如下所示:
{
text: "Success is the ability to go from one failure to another with no loss of enthusiasm.",
publisher: user12345,
rank: 14,
//some more data
}
应用程序结构如下所示:
所以,我对AppState树的外观感到非常沮丧。
AppState {
UserState {
UserCitationsState,
UserInfoState,
AuthState
},
RouterState,
UserPageState //State representing the other user's page viewed
//etc
}
主要问题是 - 我应该在每个状态中存储什么,因为从后端REST api按请求获取所有数据。它只是布尔值,例如:。
UserPageState {
loading: false,
loaded: true
}
还是应该存储所有信息,每次请求新的用户页面时都要替换它?每当用户导航到其他用户页面时,所有数据都从后端获取。 这对我来说是一个根本混乱的问题 - 如何使用redux来处理这类应用程序。
修改 目前我限制自己使用5个状态(5个缩减器)来代表整个应用程序:
然而,在整个应用程序状态中,我正在复制其中的许多内容。我想这很好。或者会有更好的方法吗?
export interface AppState
{
localUser: AuthState
//homePage
homeCitation: CitationState
//profilePage
profileInfo: UserState
profileCitations: CitationListState
favouriteCitations: CitationListState
subscribers: UserListState
//userPage (when local user navigates to citation publisher's profile)
userInfo: UserState
userCitations: CitationListState
userSubscribers: UserListState
//feedPage
feed: CitationListState
//.....
}
答案 0 :(得分:1)
我对此的初步想法是考虑应用程序状态,就像数据库一样。
我会使用以下reducer进行结构:
AppState: {
CitationState
UserProfileState,
UserInfo,
RouterState
}
interface CitationState {
citations: Citation[]
}
interface UserProfileState {
userProfiles: UserProfile[]
}
interface UserInfo {
userInfo: UserInfo
}
interface Citation {
id: number;
publisherId (userId): number;
rank: number;
text: string;
}
interface UserProfile {
userId: number;
citationIds: number[]
}
interface UserInfo {
userId: number;
authToken: string;
}
然后,每个智能组件将根据需要组合数据以呈现视图。例如,您可以通过检查路由用户配置文件是否与UserInfo reducer中的配置文件匹配来确定用户配置文件是否属于您自己的配置文件。
不要担心在州内创建加载/加载,这是您可以从商店的状态中获得的。由于所有数据都是可观察的,因此当您从中查询时,您将获得可用数据的最新快照。
而不是在加载用户的引用时绑定到商店的加载属性,而是为该数据构建查询。
例如:
let userCitation$ = state.select(appState => appState.citations)
.map(citations => {
let userCitation = citations.find(c => c.id === userId);
return {
loaded: !!userCitation,
userCitation: userCitation
};
});