选择器什么时候执行?恩克斯
When do selectors execute? ngxs
现场演示https://stackblitz.com/edit/angular-vw78jf
我的ngxs状态中有ToppingsStateModel
export interface ToppingsStateModel {
entities: { [ id: number ]: Topping };
selectedToppings: number[];
}
一个操作更改我的实体列表,另一个操作更改选择的浇头。
在 products.component 中,我从选择器
中获取了配料列表
export class ToppingsState {
constructor(private toppingsService: ToppingsService) {
}
@Selector()
static entities(state: ToppingsStateModel) {
console.log('getEntities', state.entities);
return state.entities;
}
@Selector([ToppingsState.entities])
static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
}
...
}
它是 product.component
export class ProductsComponent implements OnInit {
@Select(ToppingsState.toppings) toppings$: Observable<Topping[]>;
constructor(private store: Store, private actions$: Actions) {}
ngOnInit() {
const state = this.store.dispatch(new LoadToppings());
setTimeout(() => this.store.dispatch(new VisualizeToppings([1])), 2000);
this.toppings$.subscribe((toppings) => {console.log('UUUU NEW TOPPINGS!!!')});
}
}
当我发送 VisualizeToppings 操作时,我得到了新的配料值。在我的控制台中我有
action [Products] Load Toppings @ 10:57:59.735
getEntities {}
UUUU NEW TOPPINGS!!!
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!
action [Products] Visualize Toppings @ 10:58:01.744
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!
我改变了状态的另一部分。为什么在我发送 VisualizeToppings 操作时选择器再次执行?我做错了什么?
@Selector
存在一个已知问题,其中容器状态 class 的模型始终假定为第一个参数。参见:https://github.com/ngxs/store/issues/386#issuecomment-395780734
这是你的问题...因为第一个参数,你的选择器依赖于状态模型 ToppingsStateModel
和指定的 ToppingsState.entities
选择器。
@Selector([ToppingsState.entities])
static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
}
这会导致在 ToppingsStateModel 的任何部分发生更改时重新计算选择器。作为一种变通方法,您可以将选择器移动到另一个 class 而不是 State class 并删除第一个参数。我将这些称为查询 classes。这称为元选择器,请参阅此处的文档:https://ngxs.gitbook.io/ngxs/concepts/select#meta-selectors
这将作为 NGXS v4 中重大更改的一部分得到修复(参见 https://github.com/ngxs/store/issues/827) and there is currently a PR for a feature flag to change this behaviour before NGXS v4 arrives. See: https://github.com/ngxs/store/pull/858
我希望这有助于解释问题。
现场演示https://stackblitz.com/edit/angular-vw78jf
我的ngxs状态中有ToppingsStateModel
export interface ToppingsStateModel {
entities: { [ id: number ]: Topping };
selectedToppings: number[];
}
一个操作更改我的实体列表,另一个操作更改选择的浇头。 在 products.component 中,我从选择器
中获取了配料列表export class ToppingsState {
constructor(private toppingsService: ToppingsService) {
}
@Selector()
static entities(state: ToppingsStateModel) {
console.log('getEntities', state.entities);
return state.entities;
}
@Selector([ToppingsState.entities])
static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
}
...
}
它是 product.component
export class ProductsComponent implements OnInit {
@Select(ToppingsState.toppings) toppings$: Observable<Topping[]>;
constructor(private store: Store, private actions$: Actions) {}
ngOnInit() {
const state = this.store.dispatch(new LoadToppings());
setTimeout(() => this.store.dispatch(new VisualizeToppings([1])), 2000);
this.toppings$.subscribe((toppings) => {console.log('UUUU NEW TOPPINGS!!!')});
}
}
当我发送 VisualizeToppings 操作时,我得到了新的配料值。在我的控制台中我有
action [Products] Load Toppings @ 10:57:59.735
getEntities {}
UUUU NEW TOPPINGS!!!
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!
action [Products] Visualize Toppings @ 10:58:01.744
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!
我改变了状态的另一部分。为什么在我发送 VisualizeToppings 操作时选择器再次执行?我做错了什么?
@Selector
存在一个已知问题,其中容器状态 class 的模型始终假定为第一个参数。参见:https://github.com/ngxs/store/issues/386#issuecomment-395780734
这是你的问题...因为第一个参数,你的选择器依赖于状态模型 ToppingsStateModel
和指定的 ToppingsState.entities
选择器。
@Selector([ToppingsState.entities])
static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
}
这会导致在 ToppingsStateModel 的任何部分发生更改时重新计算选择器。作为一种变通方法,您可以将选择器移动到另一个 class 而不是 State class 并删除第一个参数。我将这些称为查询 classes。这称为元选择器,请参阅此处的文档:https://ngxs.gitbook.io/ngxs/concepts/select#meta-selectors
这将作为 NGXS v4 中重大更改的一部分得到修复(参见 https://github.com/ngxs/store/issues/827) and there is currently a PR for a feature flag to change this behaviour before NGXS v4 arrives. See: https://github.com/ngxs/store/pull/858
我希望这有助于解释问题。