角度ngrx迁移错误“属性'选择"在类型“可观察的状态"上不存在. [英] Angular ngrx migration error "Property 'select' does not exist on type 'Observable<State>'"

查看:90
本文介绍了角度ngrx迁移错误“属性'选择"在类型“可观察的状态"上不存在.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将现有应用程序从ngrx v2迁移到v4,并且在

I am attempting to migrate an existing application from ngrx v2 to v4, and am having a bit of trouble with a scenario I do not see covered in the migration document. The migration document has you remove @ngrx/core, but I am not sure what to do with my reducers that import from @ngrx/core/add/operator/select and select from an Observable. I am getting the error "Property 'select' does not exist on type 'Observable'" from all of the reducers.

/actions/action-with-payload.ts-迁移的解决方法

/actions/action-with-payload.ts -- Workaround for the migration

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

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

/actions/users-list.ts

/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

/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

/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

/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

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 { }

推荐答案

我不确定为什么需要导入select.即使在版本2中,我也从未这样做过.我将尝试展示代码对于单个实体的外观.

I am not sure why you need to import select. I never did that even in version 2. I will try to show how the code should look like for a single entity.

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);

在组件中使用select像这样:

In component use select like this :

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

可能会有很多编译错误,但这只是一个伪代码,用于向您解释事情的工作方式.

There might be lot of compilation errors, but this is just a pseudocode to explain you how things work.

您可以检查 https://github.com/ngrx/platform/tree/master/example-app 获取详细示例.但是我个人很难理解它是如何工作的.如果您对此感兴趣,我可能会在这个周末写一个博客.

You can check https://github.com/ngrx/platform/tree/master/example-app for detailed example. But personally I struggled a lot to understand how it works. I will probably write a blog this weekend on this if you are interested.

这篇关于角度ngrx迁移错误“属性'选择"在类型“可观察的状态"上不存在.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆