Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度NGX不会重新计算选择器,除非所选数据在状态中更新_Javascript_Angular_Ngxs_Angular State Managmement - Fatal编程技术网

Javascript 角度NGX不会重新计算选择器,除非所选数据在状态中更新

Javascript 角度NGX不会重新计算选择器,除非所选数据在状态中更新,javascript,angular,ngxs,angular-state-managmement,Javascript,Angular,Ngxs,Angular State Managmement,我的NGXS状态定义如下 export interface Project{ _id:string, name:string } export class ProjectStateModel { projects: Project[]; } @State<ProjectStateModel>({ name: 'Projects', defaults: { projects: [{_id:'111', name:'Project 1'

我的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个项目;两个选择器,一个用于获取所有项目,另一个用于获取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)
由于上面的选择器没有对状态令牌、状态类或其他选择器的任何引用,因此默认情况下,选择器将在每次状态更改时运行。选择器的功能在于,您可以在它们的基础上创建细粒度选择器

@Selector() // <-- no selector injected 
static getById(state: ProjectStateModel)
另一种选择是使用动态选择器。基本上,在需要时创建选择器,并传入所需的参数。以下是一个例子:

该示例没有显示最佳实践,而且非常粗糙。例如,您不能更改id,但它确实显示了实现所需的另一种方法


精彩资源:

谢谢你的回答。这解决了眼前的问题,但这是按id定义选择器的最佳方法吗?我的意思是,首先有一个选择器,它根据整个状态的id进行过滤,然后再使用之前存储的选择器创建一个动态选择器??NGXS的大多数代码库都使用引擎盖下的createSelector来生成选择器。加入slack频道如果你需要更多帮助,你通常会有更好的讨论。我也在那里。