使用 Angular2 ngrx 的类似 Twitter 的应用程序。构建 AppState
Twitter-like app with Angular2 ngrx. Structuring AppState
我最近一直在研究 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
}
应用程序结构如下所示:
- 主页 - 使用 registration/login 表格或随机引用(如果已登录)。
- 带标签的个人资料页面
- 包含用户发布的所有引用的选项卡和用于发布新引用的表格。
- 个人资料
- 引文提要页面
- 用于查看与上述结构类似的其他用户个人资料的页面。 (当用户点击引文的出版商时)。
因此,我对 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
- 用户状态
- 用户列表状态
- 引用状态
- 引文列表状态
但是,在整个应用程序状态下,我复制了其中的许多内容。我想这很好。或者有更好的方法吗?
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 reducer 中的匹配来确定用户配置文件是否是您自己的。
不要担心在状态中创建 loading/loading,这是您可以从商店状态中得出的东西。由于所有数据都是可观察的,因此当您从中查询时,您将获得可用数据的最新快照。
加载用户的引文时,不是绑定到商店的加载 属性,而是为该数据构建查询。
例如:
let userCitation$ = state.select(appState => appState.citations)
.map(citations => {
let userCitation = citations.find(c => c.id === userId);
return {
loaded: !!userCitation,
userCitation: userCitation
};
});
我最近一直在研究 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
}
应用程序结构如下所示:
- 主页 - 使用 registration/login 表格或随机引用(如果已登录)。
- 带标签的个人资料页面
- 包含用户发布的所有引用的选项卡和用于发布新引用的表格。
- 个人资料
- 引文提要页面
- 用于查看与上述结构类似的其他用户个人资料的页面。 (当用户点击引文的出版商时)。
因此,我对 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
- 用户状态
- 用户列表状态
- 引用状态
- 引文列表状态
但是,在整个应用程序状态下,我复制了其中的许多内容。我想这很好。或者有更好的方法吗?
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 reducer 中的匹配来确定用户配置文件是否是您自己的。
不要担心在状态中创建 loading/loading,这是您可以从商店状态中得出的东西。由于所有数据都是可观察的,因此当您从中查询时,您将获得可用数据的最新快照。
加载用户的引文时,不是绑定到商店的加载 属性,而是为该数据构建查询。
例如:
let userCitation$ = state.select(appState => appState.citations)
.map(citations => {
let userCitation = citations.find(c => c.id === userId);
return {
loaded: !!userCitation,
userCitation: userCitation
};
});