我最近一直在研究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个还原器)来表示整个应用程序:
- authstate
- userstate
- UserListState
- 引用
- citationliststate
但是,在整个应用程序状态下,我正在复制其中的许多。我想很好。还是有更好的方法?
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
//.....
}
我对此的最初想法是像您将要像一个数据库一样考虑应用程序状态。
我将使用以下还原器结构:
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还原器中的一个。
来确定用户配置文件是否是您自己的配置文件。不要担心在状态下创建加载/加载,这是您可以从商店的状态中得出的东西。由于所有数据都是可观察到的,因此当您从中查询时,您将获得最新的可用数据快照。
加载用户的引用时而不是绑定商店的加载属性,而是为该数据构建查询。
例如:
let userCitation$ = state.select(appState => appState.citations)
.map(citations => {
let userCitation = citations.find(c => c.id === userId);
return {
loaded: !!userCitation,
userCitation: userCitation
};
});