【问题标题】:filter in createSelector ngrx with props使用道具过滤 createSelector ngrx
【发布时间】:2020-01-28 15:04:34
【问题描述】:

我正在尝试创建一个简单的选择器来通过 visitor_id 获取商店中的所有消息,但是,看起来如此简单的事情在 ngrx 中实现总是具有挑战性。

我正在使用 ngrx 实体,所以我已经准备好 selectAll 选择器,所以我尝试执行以下操作:

export const selectMessagesState = createFeatureSelector<MessagesState>('messages');

export const selectAllMessages =  createSelector(
    selectMessagesState,
    fromMessage.selectAll
);

export const selectMessageByVisitorId = createSelector(
    select(selectAll),
    (visitor_id) => map(val => val.filter(c => c.visitor_id == visitor_id))
);

在组件中:

export class Message {
    id: number;
    message: string;
    visitor_id: number;
    is_from_visitor: boolean;
    created_at: string;
}
public messages$ : Observable<Message[]>;

public showThread(visitor: Visitor){

   this.messages$ = this.store.select(selectMessageByVisitorId({ visitor_id: visitor.id}));

但是我在selectMessageByVisitorId 中得到了Property 'filter' does not exist on type 'unknown'。我很确定我没有遵循正确的方法。我要做的很简单,将visitor id 传递给selectMessageByVisitorId 选择器,它返回特征存储中的消息列表,由visitor_id 过滤。

更新 #1

根据@Nikhil 的建议,我将选择器更改为:

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
    select(selectAll),
    messages => messages.filter(val => val.visitor_id == visitor_id)
);

但是我得到了Property 'filter' does not exist on type 'Observable&lt;Message[]&gt;,事件虽然我导入了import { filter} from 'rxjs/operators';(我使用的是ngrx 8.0)。

所以我想尝试:

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
    select(selectAll),
    messages => messages.pipe(
            map(val => val.filter(c => c.visitor_id == visitor_id)  ) 
        )
);

但现在我在组件文件this.messages$ = this.store.select(selectMessageByVisitorId({ visitor_id: visitor.id})); 中得到Type 'Observable&lt;Observable&lt;Message[]&gt;&gt;' is not assignable to type 'Observable&lt;Message[]&gt;'.

【问题讨论】:

    标签: angular rxjs ngrx ngrx-entity


    【解决方案1】:

    这里不需要map(),只需使用filter()

    方法一:

    export const selectMessageByVisitorId = ({visitor_id}) => createSelector(   
        pipe(
         select(selectAll),
         filter(val => val.visitor_id == visitor_id)
        )
    );
    

    方法2:

    export const selectAllMessages =  createSelector(
        selectMessagesState,
        fromMessage.selectAll
    );
    
    export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
        selectAllMessages,
        messages => messages.filter(val => val.visitor_id == visitor_id)
    );
    

    然后订阅消息。

    this.messages$ = this.store.select(
      selectMessageByVisitorId({visitor_id: visitor.id})
    );
    
    this.messages$.subscribe((messages) => {
      // Handle response.
      console.log(messages);
    });
    

    【讨论】:

    • 不幸的是,没有编译,在过滤器函数上得到Property 'visitor_id' does not exist on type 'unknown'(visitor_id) 在 vscode 智能感知中也显示为Observable&lt;Message[] 类型,尽管它应该是一个数字。
    • 根据您的RxJS 版本,确保导入正确的模块。看看这个answer
    • 过滤器已导入,但问题在于过滤器函数的输入val 假定为未知
    • @YehiaA.Salam - 查看我编辑的答案,如果您有任何问题,请告诉我。
    • 非常感谢您的帮助,我更新了问题,关闭,但还没有
    猜你喜欢
    • 1970-01-01
    • 2018-06-19
    • 2018-04-10
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多