【问题标题】:@ngrx 4 store return type@ngrx 4 商店返回类型
【发布时间】:2017-08-04 02:44:06
【问题描述】:

我正在使用 Angular 4 和 @ngrx 4 创建一个 Web 应用程序,但我遇到了 Store 返回类型的问题。这是我使用Store的组件:

export class ProductEditComponent implements OnInit, OnDestroy {

  categoryMap: Map<number, Node>;
  categoryObs$: Observable<State>;
  categoryObsSubscription;

  constructor(private store: Store<State>) { }

  ngOnInit() {
    // Retrieve data from the backend.
    this.categoryObs$ = this.store.select('productTree');
    this.categoryObsSubscription = this.categoryObs$.subscribe((res: State) => {
      this.categoryMap = res.productTree;
    }, (error) => {
      console.error(error);
    });

    this.store.dispatch(new productTreeActions.LoadProductTreeAction(1));
  }

  ngOnDestroy() {
    this.categoryObsSubscription.unsubscribe();
  }

}

根据我对文档的理解,我从store.select 获得的观察者应该输入到State 接口,因为我将Store 创建为:store: Store&lt;State&gt;

但是,当我尝试将我的 observable 分配给选定的 Store (this.categoryObs$ = this.store.select('productTree');) 时,我收到此错误:

Type 'Store<Map<number, Node>>' is not assignable to type 'Observable<State>'. Types of property 'operator' are incompatible. Type 'Operator<any, Map<number, Node>>' is not assignable to type 'Operator<any, State>'. Type 'Map<number, Node>' is not assignable to type 'State'. Property 'productTree' is missing in type 'Map<number, Node>'.

我不确定自己做错了什么,因为我检查了res 的值,它对应于State 类。

这是我的还原:

export interface State {
  productTree: Map<number, Node>;
  errorMsg: string;
}

const initialState: State = {
  productTree: new Map<number, Node>(),
  errorMsg: ''
};

export function productTreeReducer(state = initialState, action: productTreeOperations.Actions): State {

  switch (action.type) {
    case productTreeOperations.LOAD_PRODUCT_TREE:
      return initialState; // Reset state

    case productTreeOperations.LOAD_PRODUCT_TREE_COMPLETE:
      return { productTree: action.payload, errorMsg: '' };

    case productTreeOperations.LOAD_PRODUCT_TREE_FAIL:
      return { productTree: undefined, errorMsg: action.payload }

    case productTreeOperations.DELETE_BRANCH:
      return deleteBranch(action.payload, state);

    case productTreeOperations.ADD_CHILD:
      return addChild(action.payload.parent, action.payload.newChild, state);

    default:
      return state;
  }
}

和行动:

export const LOAD_PRODUCT_TREE = 'load-product-tree';
export const LOAD_PRODUCT_TREE_COMPLETE = 'load-product-tree-complete';
export const LOAD_PRODUCT_TREE_FAIL = 'load-product-tree-fail';

export const DELETE_BRANCH = 'delete-branch';
export const ADD_CHILD = 'add-child';

/**
 * Loads tree from backend and resets current state.
 */
export class LoadProductTreeAction implements Action {
  readonly type = LOAD_PRODUCT_TREE;
  constructor (public payload: number) { }
}

/**
 * Returns the loaded tree from the backend.
 */
export class LoadProductTreeCompleteAction implements Action {
  readonly type = LOAD_PRODUCT_TREE_COMPLETE;
  constructor (public payload: Map<number, Node>) { }
}

/**
 * Returns an error that happened when the tree was being loaded from the backend.
 */
export class LoadProductTreeFailAction implements Action {
  readonly type = LOAD_PRODUCT_TREE_FAIL;
  constructor (public payload: string) { }
}

/**
 * Deletes an entire branch of the tree (the current node and all child nodes).
 */
export class DeleteBranchAction implements Action {
  readonly type = DELETE_BRANCH;
  constructor (public payload: Node) { }
}

/**
 * Adds a child to a node.
 */
export class AddChildAction implements Action {
  readonly type = ADD_CHILD;
  constructor (public payload: { parent: Node, newChild: Node }) { }
}

export type Actions = LoadProductTreeAction |
                      LoadProductTreeCompleteAction |
                      LoadProductTreeFailAction |
                      DeleteBranchAction |
                      AddChildAction;

【问题讨论】:

  • 听从我的建议,阅读更多有关商店的信息,并在继续之前专门查看示例应用程序!
  • 我会的!感谢您的帮助并为我澄清事情! :)

标签: angular typescript redux ngrx


【解决方案1】:

您的状态由productTree 组成,其类型为Map&lt;number, Node&gt;

export interface State {
  productTree: Map<number, Node>;
  errorMsg: string;
}

您正在从商店中选择productTree

this.categoryObs$ = this.store.select('productTree');

因此,它将返回 Map&lt;number, Node&gt; 而不是 Observable&lt;State&gt;

相反,您应该使用createFeatureSelector 返回状态,然后订阅它,如下例所示。

 // reducers.ts
import { createSelector, createFeatureSelector } from '@ngrx/store';

export interface FeatureState {
  counter: number;
}

export interface AppState {
  feature: FeatureState
}

export const selectFeature = createFeatureSelector<FeatureState>('feature');

在你的组件中使用这个selectFeature

store.select(selectFeature).subscribe(store =. {
  this.counter = store.counter;
});

Read about selectors from here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2018-03-25
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多