与Angular2 ngrx类似Twitter的应用程序。构建AppState

时间:2016-12-15 18:49:13

标签: rest angular routing redux ngrx

我最近一直在研究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个缩减器)来代表整个应用程序:

  1. AuthState
  2. UserState
  3. UserListState
  4. CitationState
  5. CitationListState
  6. 然而,在整个应用程序状态中,我正在复制其中的许多内容。我想这很好。或者会有更好的方法吗?

    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
      
      //.....
    }

1 个答案:

答案 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
           };
     });