【问题标题】:Angular 8 set state from http with NgRxAngular 8 使用 NgRx 从 http 设置状态
【发布时间】:2019-10-10 22:55:04
【问题描述】:

我的目标:使用“NgRx”的处理方式更新我的服务文件。

我正在发出 GET 请求以从我的服务中获取菜单数据,一旦该调用发生,我希望它在 NgRx 中设置我的“菜单”状态,以便我可以在任何地方访问菜单数据。

我不确定解决这个问题的最佳方法是什么。

我当前的代码:

Menu.service.ts

  constructor(private http: HttpClient, private store: Store<fromApp.AppState>) { }

  public getMenu(): Observable<Restaurant> {
    // not sure where to run this code:
    // this.store.dispatch(new MenuActions.SetMenu(menu));

    return this.http.get<Menu>('http://localhost:1234/api/menu');
  }

问题

1.) 在我的服务中分派菜单项是最佳做法吗?

2.) 调用后我应该使用“管道”运算符来调度更新吗?

3.) 如果我使用 NgRx,我觉得我不需要订阅 getMenu(),因为状态将在此文件中设置,我可以访问我通常订阅的状态到这项服务。在这里使用服务文件是否有效,还是我对ngrx采取了错误的方法?如果这不正确,还有什么替代方法?

谢谢!

【问题讨论】:

标签: javascript angular typescript redux ngrx


【解决方案1】:

在我的服务中分派菜单项是最佳做法吗?

你可以,但我不推荐,因为 NGRX 对此有影响。 Effect 代表做一些逻辑计算的副作用。

我应该在调用后使用“管道”运算符来调度更新吗?

你不应该。

如果我使用 NgRx,我觉得我不需要订阅 getMenu(),因为状态将在此文件中设置,我可以访问我通常订阅此服务的状态.在这里使用服务文件是否有效,还是我对ngrx采取了错误的方法?如果这不正确,还有什么替代方法?

你不应该。而是在您的组件中像这样订阅

例子

我有这样的服务

  getPosts(): Observable<any> {
    return this.http.get("https://jsonplaceholder.typicode.com/posts");
  }

然后我调用api的效果

 getPosts$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PostActions.LoadPosts),
      switchMap(_ => {
        return this.postService
          .getPosts()
          .pipe(
            map(
              (posts: IPost[]) => PostActions.LoadPostsSuccess({ posts }),
              catchError(errors => of(PostActions.LoadPostsFail(errors)))
            )
          );
      })
    )
  );

所以在我的容器组件中

  public posts$: Observable<IPost[]>;

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

  ngOnInit() {
    this.store.dispatch(LoadPosts());
    this.posts$ = this.store.pipe(select(selectAllPosts));
  }

<div class="row">
  <div class="col-3" *ngFor="let post of posts$ | async">
    <div class="card card-container">
      <div class="card-body">
        <h5 class="card-title">{{ post.title }}</h5>
        <p class="card-text">{{ post.body }}</p>
        <a
          class="btn btn-outline-primary"
          [routerLink]="['/posts/',post.id]"
          role="button"
          >Go to detail</a
        >
      </div>
    </div>
  </div>
</div>

当然你需要选择器来获取组件中的数据

export const selectPostState = createFeatureSelector<PostState>(
  POST_FEATURE.storekey
);

export const selectPostsEntities = createSelector(
  selectPostState,
  posts => posts.entities //object look up
);

export const selectAllPosts = createSelector(
  selectPostsEntities,
  posts => Object.keys(posts).map(key => posts[key]) // use *ngFor
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-24
    • 2021-06-26
    • 2012-07-10
    • 2020-04-11
    • 2020-04-07
    • 2017-08-30
    • 2019-12-08
    • 2018-12-05
    相关资源
    最近更新 更多