2017-08-29 17 views
1

我試圖遷移從NGRX V2到V4現有的應用程序,和我有一點麻煩的情景我沒有看到覆蓋在migration document。遷移文件有刪除@ NGRX /核心,但我不知道該怎麼跟我的減速,從@ NGRX /核心/添加/運營/選擇導入,然後從可觀察到的事情。我收到錯誤「屬性‘選擇’上鍵入‘可觀測’不存在」,從所有的減速器。角NGRX遷移錯誤「屬性‘選擇’在類型不存在‘可觀察<State>’」

/actions/action-with-payload.ts - 解決方法用於遷移

import { Action } from '@ngrx/store'; 

export class ActionWithPayload implements Action { 
    type: string; 
    payload?: any; 
} 

/actions/users-list.ts

export class UsersListActions { 
    static LOAD_USERS_LIST = '[UserManagement/Users List] Load Users List'; 
    loadUsersList(): ActionWithPayload { 
     return { 
      type: UsersListActions.LOAD_USERS_LIST 
     }; 
    } 

    static LOAD_USERS_LIST_SUCCESS = '[UserManagement/Users List] Load Users List Success'; 
    loadUsersListSuccess(users: User[]): ActionWithPayload { 
     return { 
      type: UsersListActions.LOAD_USERS_LIST_SUCCESS, 
      payload: users 
     }; 
    } 
} 

/reducers/users-list.ts

export interface UsersListState { 
    loaded: boolean; 
    loading: boolean; 
    entities: User[]; 
} 

const initialState: UsersListState = { 
    loaded: false, 
    loading: false, 
    entities: [], 
} 

export default function (state = initialState, action: ActionWithPayload): UsersListState { 
    switch (action.type) { 
    case UsersListActions.LOAD_USERS_LIST: 
     return Object.assign({}, state, { 
     loading: true 
     }); 
    case UsersListActions.LOAD_USERS_LIST_SUCCESS: 
     return Object.assign({}, state, { 
     loaded: true, 
     loading: false, 
     entities: action.payload 
     }); 
    default: 
     return state; 
    } 
}; 

export function getLoaded() { 
    return (state$: Observable<UsersListState>) => state$ 
    .select(s => s.loaded); 
} 

export function getLoading() { 
    return (state$: Observable<UsersListState>) => state$ 
    .select(s => s.loading); 
} 

export function getUsers() { 
    return (state$: Observable<UsersListState>) => state$ 
    .select(s => s.entities); 
} 

/reducers/index.ts

import usersListReducer, * as fromUsers from './users-list'; 

export interface UserManagementState { 
    usersList: fromUsers.UsersListState, 
}; 

export { usersListReducer } 

export function getUsersListState() { 
    return (state$: Observable<UserManagementState>) => state$ 
     .select(s => s.usersList); 
} 

export function getUsers() { 
    return compose(fromUsers.getUsers(), getUsersListState()); 
} 

export function getUsersLoaded() { 
    return compose(fromUsers.getLoaded(), getUsersListState()); 
} 

export function getUsersLoading() { 
    return compose(fromUsers.getLoading(), getUsersListState()); 
} 

/pages/user-list.page.ts

export class UserListPage { 
    private users$: Observable<User[]>; 
    private usersLoading$: Observable<boolean>; 

    constructor(
     private store: Store<UserManagementState>, 
    ) { 
     this.users$ = store.let(getUsers()); 
     this.usersLoading$ = store.let(getUsersLoading()); 
    } 
} 

app.module.ts

import { BrowserModule } from '@angular/platform-browser'; 
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';  
import { usersListReducer } from '/reducers';  
import { AppComponent } from './app.component'; 

@NgModule({ 
    imports: [ 
    BrowserModule, 
    BrowserAnimationsModule, 
    AppRoutingModule, 
    SharedModule.forRoot(), 
    StoreModule.provideStore({ 
     usersList: usersListReducer, 
     ... 
    }) 
    ], 
    declarations: [AppComponent], 
    bootstrap: [AppComponent], 
    providers: [ 
    ... 
    ] 
}) 
export class AppModule { } 
+0

也加入你的模塊代碼 – Skeptor

+0

我只是在使用減速器中的AppModule代碼添加特定的狀態。 provideStore需要更新(toRoot?),但我試圖在遷移模塊之前解決選擇的問題。 – Carl

+0

我會展示一個演示代碼,如果你可以創建一個plnkr,我可以給出一個工作示例。 – Skeptor

回答

1

我不知道爲什麼你需要導入select。我從來沒有,即使是在第2版。我會盡量表現出的代碼看起來應該像一個單一的實體。

import { 
    Action, 
    ActionReducerMap, 
    createFeatureSelector, 
    createSelector 
} from '@ngrx/store'; 

export function userReducer(state = initialState, action: ActionWithPayload): UsersListState { 
    switch (action.type) { 
    case UsersListActions.LOAD_USERS_LIST: 
     return Object.assign({}, state, { 
     loading: true 
     }); 
    case UsersListActions.LOAD_USERS_LIST_SUCCESS: 
     return Object.assign({}, state, { 
     loaded: true, 
     loading: false, 
     entities: action.payload 
     }); 
    default: 
     return state; 
    } 
}; 

export const getLoadedState = (state: UsersListState) => state.loaded; 
export const getLoadingState = (state: UsersListState) => state.loading; 
export const getEntitiesState = (state: UsersListState) => state.entities; 

export userStateSelector = createFeatureSelector<UsersListState>('users'); 
export const loadedState = createSelector(userStateSelector, getLoadedState); 
export const loadingState = createSelector(userStateSelector, getLoadingState); 
export const userState = createSelector(userStateSelector, getEntitiesState); 

模塊

imports: StoreModule.forFeature('users', userReducer); 

在組件的使用選擇是這樣的:

public users$: Observable<User[]>; 
constructor(private userStore: Store<UsersListState>){ 
    this.users$ = this.userStore.select(userState); 
} 

可能有很多的編譯錯誤的,但是這僅僅是一個僞解釋你是如何工作的。

您可以檢查https://github.com/ngrx/platform/tree/master/example-app了詳細的例子。但我個人努力瞭解它是如何工作的。如果您有興趣,我可能會在本週末撰寫一篇關於此的博客。

+0

非常感謝!我會對博客文章感興趣,這個過程有點痛苦,我相信我會進一步探討其他問題。我正在使用幾個星期的應用程序,這個應用程序最初基於一些angular/ngrx測試版本,所以升級有點困難,因爲我們的應用程序不再真正匹配來自ngrx 2或4的示例應用程序。 – Carl

0

創建一個包含所有狀態爲如下財產的接口,

export interface CompanyAppStore { 
    userState: UsersListState; 
    employeeState: EmployesListState; 
} 

創建一個減速機廠這是因爲下面的所有減速的集合,

export const reducers: ActionReducerMap<CompanyAppStore> = { 
    userState: userStateReducer.reducer, 
    employeeState: employeeStateReducer.reducer 
}; 

訪問減速通過導入他們如下,

import * as userStateReducer from './user.state.reducer'; 
import * as employeeStateReducer from './employee.state.reducer'; 

您的組件可以注入與這是在步驟1中創建的

constructor(private appStore: Store<CompanyAppStore>){ } 

應用程序接口現在您可以選擇使用

this.appStore 
     .select(states => states.userState) 
     .subscribe(..) 
相關問題