微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular NGXS 不会重新计算选择器,除非所选数据在状态中更新

如何解决Angular NGXS 不会重新计算选择器,除非所选数据在状态中更新

我有一个 NGXS 状态定义如下

export interface Project{
  _id:string,name:string
}

export class ProjectStateModel {
    projects: Project[];
}

@State<ProjectStateModel>({
    name: 'Projects',defaults: {
        projects: [{_id:'111',name:'Project 1'},{_id:'222',name: 'Project 2'}]
    }
})
@Selector()
    static getAll(state: ProjectStateModel) {
        return state.projects;
    }

    @Selector()
    static getById(state: ProjectStateModel) {
        return (id) => {
            return state.projects.find(p => p._id === id);
        };
    }

    @Action(ProjectsAction.Add)
    add({ getState,patchState }: StateContext<ProjectStateModel>,{ payload }: ProjectsAction.Add) 
    {
        const state = getState();
        patchState({
            projects: [...state.projects,...payload]
        })
    }

这是一个非常直接的状态实现。状态认有2个项目; 2 个选择器,一个用于获取所有项目,另一个用于通过 id 获取添加新项目的操作。

我在如下所示的组件之一中使用状态

export class ProjectDetailComponent{
    selectedPROJ: Project;
    selectedPROJ$: Observable<Project>;
    
    constructor(){
        this.selectedPROJ$ = this.store.select(ProjectState.getById)
                .pipe(map(filterFn => filterFn('111')));
        this.test = this.selectedPROJ$.subscribe(p => {
          console.log(p); //this get logged every time there is a change in state even though the project 111 hasn't changed
        })
    }
}

我面临的问题是每次我更新状态时(比如向状态添加一个新项目),即使状态中的所选项目没有改变,get by id 的选择器也会重新触发。

>

例如,在上面显示代码中,我选择了 ID 为 111 的项目。如果我分派 Add 操作来添加新项目,选择器 getById 将重新触发。

NGSX 中是否有任何方法可以定义一个参数化选择器,该选择器仅在所选项目的状态发生变化时才被触发?

我查看了 NGXS 文档中的 injectContainerState,但不明白如何将它与这个参数化选择器一起使用。

解决方法

选择器将根据其选择器进行记忆。

@Selector() // <-- no selector injected 
static getById(state: ProjectStateModel)

由于上面的选择器没有对状态标记、状态类或其他选择器的任何引用,因此默认情况下,选择器将在每次状态更改时运行。选择器的强大之处在于您可以在它们的基础上创建细粒度的选择器。

另一种选择是使用动态选择器。基本上在您需要时创建选择器并传入您需要的参数。下面是一个例子:

https://stackblitz.com/edit/ngxs-selectors-upgky4?file=src/app/app.component.ts

该示例并未展示最佳实践,而且非常粗糙。例如,您不能更改 ID。但它确实向您展示了实现您想要的目标的另一种方式。

很棒的资源:https://www.youtube.com/watch?v=y3F99IsnNvI

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。