简体   繁体   English

Angular 8 使用 NgRx 从 http 设置状态

[英]Angular 8 set state from http with NgRx

My Objective : Update my service file with the 'NgRx' way of doing things.我的目标:用“NgRx”的做事方式更新我的服务文件。

I am making a GET request to fetch menu data from my service, as soon as that call occurs, I want it to set my 'menu' state in NgRx, so that I can access the menu data everywhere.我正在发出 GET 请求以从我的服务中获取菜单数据,一旦该调用发生,我希望它在 NgRx 中设置我的“菜单”状态,以便我可以在任何地方访问菜单数据。

I'm not sure what the best way to approach this is.我不确定解决这个问题的最佳方法是什么。

My current code:我目前的代码:

Menu.service.ts菜单.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');
  }

Questions :问题

1.) Is it best practice to dispatch the menu item in my service? 1.) 在我的服务中发送菜单项是最佳实践吗?

2.) Should I use the 'pipe' operator after the call is made to dispatch the update? 2.) 在调用发送更新后,我应该使用“管道”操作符吗?

3.) If I'm using NgRx, I feel like I don't need to subscribe to getMenu() , since the state will be set in this file, and I can just access state where I'd normally subscribe to this service. 3.) 如果我使用 NgRx,我觉得我不需要订阅getMenu() ,因为状态将在此文件中设置,我可以访问我通常订阅此服务的状态. Is using the service file here valid, or am I taking the wrong approach for ngrx?在这里使用服务文件是否有效,还是我对 ngrx 采取了错误的方法? If this isn't correct, what is the alternative?如果这不正确,有什么替代方法?

Thanks!谢谢!

Is it best practice to dispatch the menu item in my service?在我的服务中调度菜单项是最佳实践吗?

You can but I wouldnt recommend because NGRX has effect for that.你可以,但我不会推荐,因为 NGRX 对此有影响。 Effect stand for side effect to do some logic calculation. Effect 代表副作用做一些逻辑计算。

Should I use the 'pipe' operator after the call is made to dispatch the update?在调用发送更新后,我应该使用“管道”运算符吗?

You should not.你不应该。

If I'm using NgRx, I feel like I don't need to subscribe to getMenu(), since the state will be set in this file, and I can just access state where I'd normally subscribe to this service.如果我使用 NgRx,我觉得我不需要订阅 getMenu(),因为状态将在这个文件中设置,我可以访问我通常订阅此服务的状态。 Is using the service file here valid, or am I taking the wrong approach for ngrx?在这里使用服务文件是否有效,还是我对 ngrx 采取了错误的方法? If this isn't correct, what is the alternative?如果这不正确,有什么替代方法?

You should not.你不应该。 Instead subcribe like this in your component而是在您的组件中像这样订阅

Example例子

I have service like this我有这样的服务

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

Then my effect to call the api然后我调用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)))
            )
          );
      })
    )
  );

So in my container component所以在我的容器组件中

  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>

Of course you will need selector to get the data in your component当然,您需要选择器来获取组件中的数据

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM