IONIC& NGRX:处于初始状态的问题

时间:2018-04-20 08:35:52

标签: angular ionic-framework redux ngrx

我的Ionic应用程序中有Ngrx的问题。
我的商店由两种类型的对象“Compteur”和“Prize []”组成 我使用ngrx实体作为“奖品”对象,并且工作得非常好。 但是使用Compteur对象时,初始状态似乎被设置为unifined,因此,我的选择器使应用程序崩溃。

如果我不尝试订阅,请完美存储构建 我怎样才能解决这个问题? 它是如何工作的?

我有这个错误:

Runtime Error
Cannot read property 'compteur' of undefined
Stack
TypeError: Cannot read property 'compteur' of undefined
    at http://localhost:8100/build/main.js:100:145
    at http://localhost:8100/build/vendor.js:27678:30
    at memoized (http://localhost:8100/build/vendor.js:27615:28)
    at defaultStateFn (http://localhost:8100/build/vendor.js:27649:39)
    at http://localhost:8100/build/vendor.js:27681:36
    at MapSubscriber.memoized [as project] (http://localhost:8100/build/vendor.js:27615:28)
    at MapSubscriber._next (http://localhost:8100/build/vendor.js:56535:35)
    at MapSubscriber.Subscriber.next (http://localhost:8100/build/vendor.js:22085:18)
    at MapSubscriber._next (http://localhost:8100/build/vendor.js:56541:26)
    at MapSubscriber.Subscriber.next (http://localhost:8100/build/vendor.js:22085:18)

在我的app.component.ts中,我称之为选择器:

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any = HomePage;
  compteur$: Observable<Compteur>;
  prises$: Observable<Prise[]>;
  pages: Array<{ title: string, component: any }>;

  constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public store: Store<AppState>) {
    this.initializeApp();
    // used for an example of ngFor and navigation
    this.pages = [
      {title: 'Accueil', component: HomePage},
      {title: 'Configuration', component: ListPage}
    ];


    this.compteur$ = this.store.select(fromCompteur.getCompteur);
    this.compteur$.subscribe(()=> {
       console.log("NOT WORKING");
    });

    this.prises$ = this.store.select(fromPrise.getPrise);
    this.prises$.subscribe(()=>{
      console.log("WORKING");
    });
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      this.store.dispatch(new fromCompteurActions.LoadAction());
      this.store.dispatch(new fromPriseActions.LoadAction());
    });
  }

  openPage(page) {
    this.nav.setRoot(page.component);
  }
}

compteur.actions.ts:

export const LOAD_COMPTEUR = "[COMPTEUR] LOAD";
export const LOAD_COMPTEUR_COMPLETED = "[COMPTEUR] LOAD COMPLETED";
export const UPDATE_COMPTEUR = "[COMPTEUR] UPDATE";

export class LoadAction implements Action {
  readonly type = LOAD_COMPTEUR;
  constructor(){};
}

export class LoadCompletedAction implements Action {
  readonly type = LOAD_COMPTEUR_COMPLETED;
  constructor(public payload: {compteur: Compteur}){};
}

export class UpdateAction implements Action {
  readonly type = UPDATE_COMPTEUR;
  constructor(public payload: {compteur: Compteur}){};
}

export type compteurActionType =
  | LoadAction
  | LoadCompletedAction
  | UpdateAction
  ;

compteur.reducer.ts

const initialState : CompteurState = {
  compteur: null,
  loading: false
};

export function reducer(state = initialState,
                        action: fromCompteur.compteurActionType): CompteurState{
  switch (action.type){
    case fromCompteur.UPDATE_COMPTEUR: {
      return {
        compteur: action.payload.compteur,
        loading: false
      };
    }
    case fromCompteur.LOAD_COMPTEUR: {
      return {...state,
      loading: true
      };
    }
    case fromCompteur.LOAD_COMPTEUR_COMPLETED: {
      return {
        compteur: action.payload.compteur,
        loading: false
      };
    }
    default: {
      return state;
    }
  }

}

export const getCompteurState = createFeatureSelector<CompteurState>('compteur');
export const getCompteur = createSelector(getCompteurState, (state: CompteurState) => state.compteur);

export const getLoading = createSelector(getCompteurState, (state: CompteurState) => state.loading);

减速器/ index.ts

export const reducers: ActionReducerMap<AppState> = {
  priseState: priseReducer.reducer,
  compteurState: compteurReducer.reducer
};

export function logger(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
  return function(state: AppState, action: any): AppState {
    console.log('state', state);
    console.log('action', action);
    return reducer(state, action);
  };
}

export const metaReducers: MetaReducer<AppState>[] = [logger];

compteur.effects.ts

@Injectable()
export class CompteurEffects {

  constructor(private actions$: Actions,
              private dataService : DataService){};

  @Effect()
  loadCompteur$: Observable<Action> = this.actions$
    .ofType(fromCompteur.LOAD_COMPTEUR)
    .switchMap(()=>
      this.dataService.getCompteur()
        .map(data => new fromCompteur.LoadCompletedAction({ compteur: data })
        )
    );


}

app.state.ts

export interface AppState {
  priseState: PriseState;
  compteurState: CompteurState;
}

export interface PriseState extends EntityState<Prise>{
  selectedPriseId: string | number | null,
  loading: boolean
}

export interface CompteurState {
  compteur: Compteur,
  loading: boolean
}

的package.json

"dependencies": {
    "@angular/common": "5.0.3",
    "@angular/compiler": "5.0.3",
    "@angular/compiler-cli": "5.0.3",
    "@angular/core": "5.0.3",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@ionic-native/core": "4.4.0",
    "@ionic-native/splash-screen": "4.4.0",
    "@ionic-native/status-bar": "4.4.0",
    "@ionic/storage": "2.1.3",
    "@ngrx/core": "^1.2.0",
    "@ngrx/effects": "^5.2.0",
    "@ngrx/entity": "^5.2.0",
    "@ngrx/store": "^5.2.0",
    "@ngrx/store-devtools": "^5.2.0",
    "chart.js": "^2.7.2",
    "ionic-angular": "3.9.2",
    "ionicons": "3.0.0",
    "ng2-charts": "^1.6.0",
    "rxjs": "5.5.2",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.8",
    "typescript": "2.4.2"
  }

1 个答案:

答案 0 :(得分:0)

好的,我发现了我的错误:
我在compteur.reducer.ts中犯了一个错误 只需要替换它:

export const getCompteurState = createFeatureSelector<CompteurState>('compteur');

通过

export const getCompteurState = createFeatureSelector<CompteurState>('compteurState');