我正在尝试将我的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)
我究竟做错了什么?
我按照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条件添加到减速器解决了这个问题。
我已经实现了类似的用例。你的尝试很好,我是这样工作的:
@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 ,这样我就不会感到困惑。
| 归档时间: |
|
| 查看次数: |
5331 次 |
| 最近记录: |