我无法从NgRx商店中获取商品,并且可观察到的商品仍未定义

时间:2020-06-24 03:47:48

标签: angular ngrx

import { Post } from './models/post.model';
import { AppActions, SET_POSTS } from './app.actions';

export interface State {
    posts: Post[]
}

const initialState: State = {
    posts: []
}

export function appReducer(state = initialState, action: AppActions) {
    switch(action.type) {
        case SET_POSTS:
            return {
                ...state,
                posts: action.payload
            }
        default: 
            return state;
    }
}

export const getPosts = (state: State) => state.posts;

这就是我在减速器方面的功能,我认为我没有从官方文档中提供的示例中编写出任何问题。

  ngOnInit() {
    this.posts$ = this.store.select(fromPost.getPosts);
    this.postService.getPosts();
  }

现在,postService正在运行,我已经能够通过登录对其进行确认,但是由于某种原因,它永远不会被填充。

 .subscribe((posts: Post[]) => {
    this.store.dispatch(new AppAction.SetPosts(posts));
 }

当我记录帖子时,我得到了预期的输出,因此我想知道是否是不正确地调用或处理了调度。

import { Action } from '@ngrx/store';
import { Posts } from './models/post.model';

export const SET_POSTS = 'Set Posts';

export class SetPosts implements Action {
    readonly type = SET_POSTS;
  
    constructor(public payload: Post[]) {}
}

export type AppActions = SetPosts;

这是发布操作,所以我看不到有什么问题吗?

更新:

   this.posts$ = this.store.select(fromPost.selectPosts);
   this.postService.getPosts();
   console.log(this.posts$);
   this.posts$.subscribe( value => console.log(value));
   //Object { _isScalar: false, actionsObserver: {…}, reducerManager: {…}, source: {…}, operator: {…} }

   //undefined

我还对减速器进行了一些更改:

const getPosts = (state: State) => state.posts;

export const selectState = (state: State) => state;
export const selectPosts = createSelector(
  selectState,
  getPosts
);

在html文件中执行此操作后,我什么也没得到:

<div *ngIf="(posts$ | async) as posts">
  <div *ngFor="let post of posts">
    {{ post.title}}
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

简短的回答,您已经编写了一个选择器将帖子绑定到UI。

创建Selector.ts文件

import { createSelector } from '@ngrx/store';
import * as fromPost from 'post.reducer'

export const selectState = (state: State) => state;
export const selectPost = createSelector(
  selectState,
  fromPost.getPosts
);

在您的组件中

constructor() {
  this.store.dispatch(new LoadPost())
}

ngOnInit() {
    this.posts$ = this.store.select(selectPost);
  }

创建一个调用postService的效果,异步服务是商店的副作用,应通过效果来处理。 Documentation for Setting up effects

创建帖子action.ts

import { Action } from '@ngrx/store'

export enum PostActionTypes {
  LoadPost = '[Post] Load Post',
  SetPosts = '[Post] Load Post Success',
  LoadPostFailure = '[Post] Load Post Failure',
}

export class LoadPost implements Action {
  readonly type = PostActionTypes.LoadPost
}

export class SetPosts implements Action {
  readonly type = PostActionTypes.SetPosts
  constructor(public payload: Post[]) {}
}

export class LoadPostFailure implements Action {
  readonly type = PostActionTypes.LoadPostFailure
  constructor(public payload: any) {}
}

export type PostActions = 
| LoadPost
| SetPosts
| LoadPostFailure

创建后期效果。ts

import { Injectable } from '@angular/core'
import { Actions, ofType } from '@ngrx/effects'
import { of } from 'rxjs'
import { catchError, map, switchMap } from 'rxjs/operators'

@Injectable()
export class PostEffects {
  constructor(private postService: PostService, private actions$: Actions) {}

  @Effect()
  loadPosts$ = this.actions$.pipe(
    ofType(PostActions.LoadPost),
    switchMap(() => {
      return this.postService.getPosts().pipe(
        map(posts => new SetPosts(posts)),
        catchError(error => of(new LoadPostFailure(error)))
      )
    })
  )
}

注意:效果是可注入类,请确保将它们添加到

NgModule({
  declarations: [],
  imports: [
    ...    
    EffectsModule.forRoot([ ... effects ]), // Effect classes as CSV
    ...
  ]
})