ngrx归一化状态选择器

时间:2018-12-15 10:39:03

标签: ngrx normalizr

我正在重写一个与ngrx一起使用的Ionic项目,因为它正在增长,并且我需要保持集中状态。

我已经使用ngrx实现了它,并在Normalizr的帮助下使用归一化状态。

现在我对如何将填充的对象传递给哑组件有疑问:

假设我有两个接口:

interface Conversation {
    date: Date,
    lastMessage: string //this is the id of a message entity coming from normalizr
}

 interface Message {
       content: string
}

现在,当我试图将所有对话传递给愚蠢的组件时,我正在使用这样的选择器:

getConversations() {

    //select all the conversations to have a shape of Conversation[]
    let conversations$ = this.store.select(state => Object.keys(state.entities.conversations).map( (id:string) => state.entities.conversations[id] ));

    //select all the messages in a shape { [id:string] : Message }
    let messages$ = this.store.select(state => state.entities.messages);

    return Observable.combineLatest(
      conversations$,
      messages$,
      (conversations, messages) => {
        return conversations.map(conversation => {
          return { ...conversation, lastMessage: messages[conversation.lastMessage] }

        });
      }
    )
  }

但是我要返回的Observable不是Conversation []数组,因为

return { ...conversation, lastMessage: messages[conversation.lastMessage] }

在'lastMessage'中放置了Message类型的对象,而不是String。

我尝试使用对象类型而不是字符串的接口

interface Conversation {
       date: Date,
       lastMessage: Message
    }

但是我不能使用

这样的选择器
this.store.select(state => state.entities.messages[conversation.lastMessage]

因为它不再是字符串了。

我该如何实现?

谢谢

1 个答案:

答案 0 :(得分:0)

此问题的简短答案如下:

您需要从上一条消息中选择react-scripts start属性,如:

content

更长的答案:

使用选择器也可以实现相同的目的,其优点是与RxJS运算符相比,它更可重用。

  

选择器是一个纯函数,它以状态为参数,   返回商店状态的一部分。而不是只返回   存储在商店中的数据,选择器可以根据以下内容计算派生数据   可用数据。这样您就可以只存储基础知识,   状态树尽可能紧凑。另一个重要的部分是   选择器可以组成,即:一个选择器可以采用一个或   多个其他选择器作为其输入。

例如:

return { ...conversation, lastMessage: messages[conversation.lastMessage].content }

在组件中选择要选择的书籍,您可以执行以下操作:

// getters
export const selectUser = (state: AppState) => state.selectedUser;
export const selectAllBooks = (state: AppState) => state.allBooks;

// create a selector with `createSelector` and use the getters above
export const selectVisibleBooks = createSelector(
  selectUser,
  selectAllBooks,
  (selectedUser: User, allBooks: Books[]) => {
    if (selectedUser && allBooks) {
      return allBooks.filter((book: Book) => book.userId === selectedUser.id);
    } else {
      return allBooks;
    }
  }
);

更多信息: