2017-08-29 125 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(..) 
相关问题