ngrx状态未定义

时间:2017-03-12 02:14:38

标签: angular ngrx

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

在我的app.module.ts Object.prototype.getTypeStrict = function() { "use strict"; return typeof this; }; console.log("".getTypeStrict()); // string

中注册的示例服务类
providers

我已经验证了我的操作,reducer和效果正在按预期工作,但是,当我订阅组件中的服务状态时,它会返回@Injectable() export class PatientService { state: Observable<PatientState>; constructor( private store: Store<AppState>, ) { this.state = store.select<PatientState>('patients'); } }

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

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.
    });
  }

}

我做错了什么?

3 个答案:

答案 0 :(得分: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;
  }
}

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

@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();
  }

}

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

答案 1 :(得分:0)

我认为您缺少此参考资料,

this.state = store.select<PatientState>('patients');

应该是

this.state = this.store.select<PatientState>('patients');

答案 2 :(得分:0)

我按照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;
      }
    }
 }

以前,我的代码没有default条件,并且由于这个事实而返回undefined。将default条件添加到reducer可以解决该问题。