[Angular 2] Handle Reactive Async opreations in Service

Posted Answer1215

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Angular 2] Handle Reactive Async opreations in Service相关的知识,希望对你有一定的参考价值。

When you use ngrx/store and you want to fire a service request. When it sucessfully return the response, you need to dispatch action to tell the store update.

 

So one pattern can be considered to follow is:

import {Http, Headers} from @angular/http;
import {Injectable} from @angular/core;
import {Store} from @ngrx/store;
import {Observable} from "rxjs/Observable";
import rxjs/add/operator/map;

import {AppStore} from ../models/appstore.model;
import {Item} from ../models/item.model;

const BASE_URL = http://localhost:3000/items/;
const HEADER = { headers: new Headers({ Content-Type: application/json }) };

@Injectable()
export class ItemsService {
  items: Observable<Array<Item>>;

  constructor(private http: Http, private store: Store<AppStore>) {
    this.items = store.select(items);
  }

  loadItems() {
    this.http.get(BASE_URL)
      .map(res => res.json())
      .map(payload => ({ type: ADD_ITEMS, payload }))
      .subscribe(action => this.store.dispatch(action));
  }

  saveItem(item: Item) {
    return (item.id) ? this.updateItem(item) : this.createItem(item);
  }

  createItem(item: Item) {
     return this.http.post(`${BASE_URL}`, JSON.stringify(item), HEADER)
      .map(res => res.json())
      .do(payload => {
        const action = { type: CREATE_ITEM, payload };
        this.store.dispatch(action)
      });
  }

  updateItem(item: Item) {
    return this.http.put(`${BASE_URL}${item.id}`, JSON.stringify(item), HEADER)
      .do(action => this.store.dispatch({ type: UPDATE_ITEM, payload: item }));
  }

  deleteItem(item: Item) {
    return this.http.delete(`${BASE_URL}${item.id}`)
      .do(action => this.store.dispatch({ type: DELETE_ITEM, payload: item }));
  }
}

 

 

In this ItemService, we get Items from store:

  items: Observable<Array<Item>>;

  constructor(private http: Http, private store: Store<AppStore>) {
    this.items = store.select(items);
  }

 

To change state, it flows the style that

  • Call the backend
  • if success generate action
  • dispatch the action
 createItem(item: Item) {
     return this.http.post(`${BASE_URL}`, JSON.stringify(item), HEADER)
      .map(res => res.json())
      .do(payload => {
        const action = { type: CREATE_ITEM, payload };
        this.store.dispatch(action)
      });
  }

 

In the controller:

  saveItem(item: Item) {
    this.itemsService.saveItem(item)
      .subscribe( (res) => {this.resetItem()},
                  (err) => {console.error(err)},
                 () => {console.info("Completed")});

 

If you notice, in loadItems, I didn‘t‘ use do() to dispatch action and subscribe in controller, instead I subscribe in service, this is because in controller, it doesn‘t expect receive anything from service:

  constructor(private itemsService: ItemsService,
              private gadgetService: GadgetService,
              private store: Store<AppStore>) {
    this.items = itemsService.items;
    itemsService.loadItems();
  }

We base on async pipe to update the dom:

      <items-list [items]="items | async"
        (selected)="selectItem($event)" (deleted)="deleteItem($event)">
      </items-list>

But for createItem, deleteItem, we use do() to dispatch action and subscribe action, this is because we want to confrim weather it successfully updated, then we want to clear the input fields.

以上是关于[Angular 2] Handle Reactive Async opreations in Service的主要内容,如果未能解决你的问题,请参考以下文章

以反应形式设置 Angular 2 FormArray 值?

处理 Angular 2 中动态创建的组件的 @Input 和 @Output

如何在ng2-nouislider中更改曲目颜色

React 2 - 入门

Angular 数据绑定不适用于 async/await,但它适用于 Promise

React i18next 和更改语言的正确方法