TypeError:无法读取getPatientEntities

时间:2017-07-13 13:12:43

标签: angular ngrx ngrx-effects ngrx-store

我正在尝试解决我在我的一个应用程序中使用ngrx遇到的问题。 由于这是我的第一个ngrx项目,因此我按照ngrx示例应用程序构建了应用程序实体的操作,效果和缩减器。

我的应用程序中有一个患者实体,我已经创建了以下操作和reducer:

  1. 患者行动:

    import { Action } from '@ngrx/store';
    import { IPatient } from '../../../interfaces/';
    
    export const LOAD_PATIENT =    '[Patient] Load';
    export const ADD_PATIENT =     '[Patient] Add';
    export const DELETE_PATIENT =  '[Patient] Delete';
    
    export class LoadPatientAction implements Action {
        readonly type = LOAD_PATIENT;
    }
    
    export class AddPatientAction implements Action {
        readonly type = ADD_PATIENT;
        constructor(public patient: IPatient) { }
    }
    
    export class DeletePatientAction implements Action {
        readonly type = DELETE_PATIENT;
        constructor(public patient: IPatient) { }
    }
    
    
    export type PatientActions = LoadPatientAction
                               | AddPatientAction
                               | DeletePatientAction;
    
  2. 减速器:

    import { createSelector } from 'reselect';
    
    import { IPatient, IPatientState } from '../../../interfaces/';
    
    import { PatientState } from '../../../models/';
    
    import { patientActions } from '../../actions/patient/';
    
    
    export interface State {
        patient: IPatient | null;
        loaded: boolean;
    }
    
    export const initialState: State = {
        patient: null,
        loaded: false
    }
    
    export function patientReducer(state = initialState,
                             action: patientActions.PatientActions): State {
    
        switch (action.type) {
    
            case patientActions.LOAD_PATIENT: {
    
                return Object.assign({}, state, { loaded: true });
    
            }
    
            case patientActions.ADD_PATIENT: {
    
                const patient = action.patient;
    
                if (state.patient.id === patient.id ) { return state; }
    
                return { patient: patient, loaded: false };
    
            }
    
            case patientActions.DELETE_PATIENT: {
    
                const patient: IPatient = action.patient;
    
                return state.patient && (patient.id === state.patient.id) ?
                       { patient: null, loaded: false } : state;
    
            }
    
            default: { return state; }
    
        }
    }
    
    
    export const getPatient = (state: State) => state.patient;
    
    export const isPatientLoaded = (state: State) => state.loaded;
    
  3. reducers的index.ts文件如下所示。 (我省略了与患者实体无关的所有部分......):

    import { IDpxStates,
             IUnitState,
             ICollectionState,
             ISearch,
             ILayout,
             ILayoutTypes,
             IPatient,
             IDpxReducers } from '../../interfaces/';
    
    import { DpxState, DpxStateReducer } from '../../models/';
    
    import { createSelector } from 'reselect';
    
    import { State, Store, ActionReducer } from '@ngrx/store';
    
    import * as fromRouter from '@ngrx/router-store';
    
    import { environment } from '../../../environments/environment';
    
    import { storeFreeze } from 'ngrx-store-freeze';
    
    import { combineReducers } from '@ngrx/store';
    
    import * as fromLayout from './layout/layout.reducer';
    
    import * as fromPatient from './patients/patient/patient.reducer';
    
    const reducers: IDpxReducers = {
        layoutReducer: fromLayout.layoutReducer,
        patientReducer: fromPatient.patientReducer,
        routerReducer: fromRouter.routerReducer
    }
    
    const developmentReducer: ActionReducer<IDpxStates> = compose(storeFreeze, combineReducers)(reducers);
    const productionReducer: ActionReducer<IDpxStates> = combineReducers(reducers);
    
    export function reducer(state: any, action: any) {
        if (environment.production) {
            return productionReducer(state, action);
        } else {
            console.log(developmentReducer(state, action));
            return developmentReducer(state, action);
        }
    }
    
    export const getPatient = (state: IDpxStates) => state.patient;
    
    export const isPatientLoaded = (state: IDpxStates) => state.loaded;
    
  4. IDpxStates和IDpxReducers接口:

    export interface IDpxReducers {
        ...
        readonly patientReducer: (state: IPatientState, action: patientActions.PatientActions) => IPatientState;
        ...
    }
    
    export interface IDpxStates {
        ...
        readonly patientState: IPatientState;
        ...
    }
    
    export interface IPatientState {
        patient: IPatient | null;
        loaded: boolean;
    }
    
  5. 现在我尝试将患者从仪表板容器中取出,然后将其传递给标题组件:

         import { Component, ChangeDetectionStrategy } from '@angular/core';
    
         import { Router } from '@angular/router';
    
         import { FormGroup } from '@angular/forms';
    
         import { Observable } from 'rxjs/Rx';
    
         import { Store } from '@ngrx/store';
    
         import * as reducer from '../../state/reducers/';
    
         import * as layout from '../../state/actions/layout/';
    
         import { patientActions } from '../../state/actions/patient/';
    
         import { IDpxStates, IPatient } from '../../interfaces/';
    
         @Component({
             selector: 'app-dashboard',
             changeDetection: ChangeDetectionStrategy.OnPush,
             template:
             `
             <app-header
                  [routerLinks]="routerLinks"
                  [patient]="patient$ | async"
                  (addPatient)="openAddPatient()"
                  (addDrug)="openAddDrug()"
                  (addIndication)="openAddIndication()">
            </app-header>
            <router-outlet></router-outlet>
            `,
            styleUrls: ['_dashboard.component.scss']
        })
    
        export class DashboardComponent {
    
            patient$: Observable<IPatient>;
    
            showAddPatient$: Observable<boolean>;
    
            showAddDrug$: Observable<boolean>;
    
            showAddIndication$: Observable<boolean>;
    
            routerLinks: {addPatient: string, addDrug: string, addIndication: string} =
            {addPatient: 'patient/add',
             addDrug: 'patient/${patient$.id}/drugs/add',
             addIndication: 'patient/${patient$.id}/indications/add'};
    
            constructor(private _store: Store<IDpxStates>, private _router: Router) {
    
                this.patient$ = this._store.select(reducer.getPatient);
                this.showAddPatient$ = this._store.select(reducer.getVisible);
                this.showAddDrug$ = this._store.select(reducer.getVisible);
                this.showAddIndication$ = this._store.select(reducer.getVisible);
    
                if (this.patient$.isEmpty) { this._router.navigateByUrl('dashboard/patient/add'); }
    
            }
    
            openAddPatient() { this._store.dispatch(new layout.LayoutActions.OpenAddPatientFormAction()); }
    
            openAddDrug() { this._store.dispatch(new layout.LayoutActions.OpenAddDrugFormAction()); }
    
            openAddIndication() { this._store.dispatch(new layout.LayoutActions.OpenAddIndicationFormAction()); }
    
        }
    

    当访问仪表板容器时,我在控制台上收到以下错误:

        RROR TypeError: Cannot read property 'patient' of undefined
    at getPatient (patient.reducer.ts:55)
    

    任何人都可以帮助解决此错误吗? 感谢。

0 个答案:

没有答案