ngrx状态未定义

Bra*_*don 12 ngrx angular

我正在尝试将我的ngrx状态封装在共享服务类中,以从我的组件中抽象出实现细节.

在app.module.ts中注册的示例服务类 providers

@Injectable()
export class PatientService {

  state: Observable<PatientState>;

  constructor(
    private store: Store<AppState>,
  ) {
    this.state = store.select<PatientState>('patients');
  }

}
Run Code Online (Sandbox Code Playgroud)

我已经验证了我的操作,reducer和effect正在按预期工作,但是,当我订阅组件中的服务状态时,它返回undefined.

使用共享服务的示例组件订阅:

@Component({
  ...
})
export class DashboardComponent implements OnInit {

  constructor(
    private patientService: PatientService,
  ) {}

  ngOnInit(): void {
    // dispatches action to load patient from API
    this.patientService.loadPatient();

    this.patientService.state.subscribe(patientState => {
        console.log('patientState', patientState);
        // Does not work. Logs undefined.
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

如果我直接订阅商店,它会按预期工作.

例:

@Component({
  ...
})
export class DashboardComponent implements OnInit {

  constructor(
    private patientActions: PatientActions,
    private store: Store<AppState>,
  ) {}

  ngOnInit(): void {
    this.store.dispatch(this.patientActions.loadPatient());

    this.store.select<PatientState>('patients').subscribe(patientState => {
        console.log('patientState', patientState);
        // Works as expected.
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Geo*_*ker 5

我按照Mergasov的建议解决了这个问题,并设置了默认情况:

我有类似的问题:当一个组件订阅状态时,它state === undefined总是会得到。对我来说很困惑,但最后我发现相应的reducer没有实现魔术代码:default: return state;

这是在更大的上下文中的外观reducer.ts

  export function reducer(state: EntityState= initialEntityState, action:  actions.EntityAction) {
    switch (action.type) {
      case actions.CREATE_ENTITY_SUCCESS:
      case actions.UPDATE_ENTITY_SUCCESS: {
        const EntityDetails = action.payload;
        const entities = {
          ...state.entities,
          [Entitydetails.Id]: EntityDetails,
        };
        return {
          ...state,
          error: null,
          entities,
        };
      }
      default : {
        return state;
      }
    }
 }

Run Code Online (Sandbox Code Playgroud)

以前,我的代码没有default条件,因此返回undefined。将default条件添加到减速器解决了这个问题。


och*_*obi 0

我已经实现了类似的用例。你的尝试很好,我是这样工作的:

@Injectable()
export class PatientService {
  // Define Observable
  patientState$: Observable<PatientState>;
  constructor(private store: Store<AppState>) {
    // Get data from the store
    this.patientState$ = store.select<PatientState>('patients');
  }

  getState(): PatientState {
    // subscribe to it so i don't have to deal with observables in components
    let patientState: PatientState = null;
    this.patientState$.subscribe(ps => patientState = ps);
    return patientState;
  }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以从任何您想要的组件调用此方法,如下所示:

@Component({
  ...
})
export class DashboardComponent implements OnInit {
  patientState = new PatientState;
  constructor(
    private patientService: PatientService,
  ) {}

  ngOnInit(): void {
    // Simply get the Object from the store without dealing with observables
    this.patientState = this.patientService.getState();
  }

}
Run Code Online (Sandbox Code Playgroud)

$在 observable 的末尾使用了 ,这样我每次触摸一个变量时都知道它是否是 Observable ,这样我就不会感到困惑。

  • 这是一个非常糟糕的设计: 1. 服务并不意味着存储存储所做的任何状态。如果许多组件使用相同的服务,那么您的服务的状态将会混乱。2. 按照这种方法,不可能清除订阅(当作业完成或组件被销毁时取消订阅)。如果您不这样做,那么您的应用程序可能会出现内存泄漏。 (2认同)