我正在使用ngrx维护我的应用程序状态。
我有一个带有两个不同模块的angularjs4应用程序,它们有两个不同的缩减器,效果等。
一个用于验证,另一个用于获取电影列表。但我发现无论哪种效果被称为第二,它都会将全局应用状态写入其值。
如何防止这种情况?
以下是我的身份验证模块中的状态定义
import {User} from "../../models/user";
export interface State {
user: User,
isLoggedIn: boolean,
errors: any[]
}
export const initialState: State = {
user: null,
isLoggedIn:false,
errors:[]
};
这是auth reducer
import * as fromAuth from './auth.state';
import * as AuthActions from './auth.actions';
export function authReducer(state = fromAuth.initialState, action: AuthActions.ALL){
console.log('authReducer', action, state);
switch (action.type) {
case AuthActions.LOGIN_WITH_GOOGLE:
return {...state};
case AuthActions.LOGIN_WITH_FACEBOOK:
return {...state};
case AuthActions.LOGIN_WITH_TWITTER:
return {...state};
case AuthActions.LOGOUT:
return {...state, user: null, isLoggedIn:false};
case AuthActions.LOGIN_SUCCESSFUL:
return {...state};
case AuthActions.LOGIN_FAILED:
return {...state, errors:[{}]};
case AuthActions.REGISTER_USER:
return {...state};
case AuthActions.USER_REGISTRATION_SUCCESSFUL:
return {...state, user: action.payload, isLoggedIn:true};
case AuthActions.USER_REGISTRATION_FAILED:
return {...state, errors:[{}]};
}
}
身份验证模块定义
@NgModule({
imports: [
CommonModule,
MdToolbarModule,
EffectsModule.forFeature([AuthEffects]),
AngularFireModule.initializeApp(environment.firebase),
AngularFireAuthModule
],
exports:[AppRoutingModule],
declarations: [
LoginComponent
],
providers: [AuthService]
})
以下是电影状态定义
import {Movie} from "../../models/movie";
export interface State{
all:Movie[],
selectedMovie:Movie,
isLoading:boolean,
errors:any[]
}
export const initialState: State = {
all:[],
selectedMovie:null,
isLoading:false,
errors:[]
};
Movie Reducer
import * as MovieActions from './movies.actions';
import * as fromMovie from './movies.state';
import * as _ from 'lodash';
export function movieReducer(state = fromMovie.initialState, action:MovieActions.ALL) {
console.log('movieReducer', action, state);
switch (action.type) {
case MovieActions.GET_ALL_MOVIES:
return _.assign({}, state, {loading:true});
// return {...state, loading:true};
case MovieActions.GET_MOVIES_BY_TYPE:
return _.assign({}, state, {loading:true});
case MovieActions.GET_MOVIES_SUCCESS:
return _.assign({}, state,{all: action.payload} ,{loading:false});
// return {...state, all: action.payload, loading:false };
case MovieActions.SELECT_MOVIE:
return _.assign({}, state,{selectedMovie: action.payload} ,{loading:false});
// return {...state, selectedMovie:action.payload};
case MovieActions.UPDATE_MOVIE:
return {};
case MovieActions.DELETE_MOVIE:
return {};
}
}
终于电影模块
@NgModule({
imports: [
CommonModule,
VgCoreModule,
VgControlsModule,
VgOverlayPlayModule,
VgBufferingModule,
HttpModule,
MdCardModule,
MdButtonModule,
RouterModule,
EffectsModule.forFeature([MoviesEffects])
],
exports: [
AppRoutingModule
],
declarations: [
MoviesListComponent,
WatchMovieComponent,
EditMovieComponent,
ListFromObjectPipe
],
providers: [MovieApiService]
})
export class MoviesModule {
}
根应用状态
import * as fromMoviesReducer from '../movies/store/movies.reducer';
import * as fromMoviesState from '../movies/store/movies.state';
import * as fromAuthReducer from '../auth/store/auth.reducer';
import * as fromAuthState from '../auth/store/auth.state';
import { ActionReducerMap } from '@ngrx/store';
export interface AppState {
movies: fromMoviesState.State;
user:fromAuthState.State;
}
export const appReducers : ActionReducerMap<any> = {
movies: fromMoviesReducer.movieReducer,
user: fromAuthReducer.authReducer
};
终于app模块
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
TabsComponent
],
imports: [
BrowserModule,
MdToolbarModule,
MdTabsModule,
BrowserAnimationsModule,
MoviesModule,
ChatModule,
GamesModule,
AuthModule,
AppRoutingModule,
MdButtonModule,
StoreModule.forRoot(appReducers),
EffectsModule.forRoot([]),
StoreDevtoolsModule.instrument({
maxAge: 25 // Retains last 25 states
})
],
exports: [],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
答案 0 :(得分:9)
从Glitter的一位出色的开发者那里得到了答案!我的减速器中没有默认状态!添加默认状态如下修复了问题。
switch (action.type) {
/* my actions */
default:
return state;
}