一个字段更新时,Angular 7 ngrx会触发所有字段的订阅

时间:2020-01-18 09:00:53

标签: angular ngrx

嗨,我正在使用Ngrx作为前端项目的状态管理。最近,我发现更新状态中的一个字段时会触发所有订阅。

假设我的状态为字段A和B。相应地,我有AComponent和BComponent订阅了A和B的值。现在,如果我继续调度一个更新A的操作,则B的订阅也将被触发。时间,即使B的值未更新。

此刻,我正在做的是B的订阅功能,我检查值是否已更改,例如

if (this.B !== B) {
    //do something
}

是否可以通过某种方式调度动作来更新A,而不会触发B的订阅?还是这是NGRX的基本机制?

谢谢

更新

这是我正在使用的选择器

this._store
  .select("appState")
  .pipe<T>(pluck("B"))
  .subscribe(callback);

更新2

根据@Anarno的回答,我添加了选择器,如下所示:

const BFeatureSelector = createFeatureSelector<string>('b');
export const BSelector = createSelector(
    BFeatureSelector,
    state => state
);

同时,我在reducer中打印一条消息,以确保B更新为

case app.ActionType.B: {
    console.info("b is update in reducter");
    return Object.assign({}, state, { b: action.payload });
}

然后我通过以下三种方法在BComponent中使用此BSelector

this._store.select(BSelector).subscribe(b=> {
  console.info("b is updated 1");
  console.info(b);
});

this._store
  .pipe(
    map(state => BSelector(state))
  )
  .subscribe(b=> {
    console.info("b is updated 2");
    console.info(b);
  });

this._store
  .pipe(select(notificationSelector))
  .subscribe(b=> {
    console.info("b is updated 3");
    console.info(b);
  });

我观察到b is updated 1b is updated 3都只在组件初始化时打印一次,而b is updated 2在状态中的其他字段更新时始终打印一次。但是,每种方法中的console.info(b);都不起作用。这三种方法都不打印b的内容。

1 个答案:

答案 0 :(得分:1)

您需要一个选择器文件,并使选择器如下所示:

inline Tensor Tensor::to(ScalarType dtype, bool non_blocking, bool copy) const {
    static auto table = globalATenDispatch().getOpTable("aten::to(Tensor self, ScalarType dtype, bool non_blocking=False, bool copy=False) -> Tensor");
    return table->getOp<Tensor (const Tensor &, ScalarType, bool, bool)>(tensorTypeIdToBackend(type_id()), is_variable())(*this, dtype, non_blocking, copy);
}