RxJS Observables反对RESTful api

时间:2017-06-26 15:23:02

标签: angular rest rxjs

我很难理解如何将RxJS绑定到RESTful API。

我有两个并排的组件,都显示相同的模型列表。左手可以内联创建,更新和删除这些模型。右手应该相应更新。他们通过API服务进行交谈,API服务与API进行通信,并在Observable中保存最新的模型列表。

问题:

如何更新服务中的模型,以便将这些模型推送到组件?感觉我使用了错误的架构,但它似乎是一个非常标准的用例与RESTful API交谈。

注意:每次添加或更新内容时,我都不想重新查询API。我只是想在本地编辑列表。

以下是组件:

class EditComponent implements ngOnInit {
  private models: Model[];

  constructor(private api: ApiService)

  ngOnInit() {
    this.api.getAll().subscribe(models => this.models = models);
  }

  create(name: string) {
    this.api.create(name);
  }

  update(model: Model) {
    this.api.update(model);
  }

  delete(model: Model {
    this.api.delete(model);
  }
}

class ListComponent implements ngOnInit {
  private models: Models[];

  constructor(private api: ApiService)

  ngOnInit() {
    this.api.getAll().subscribe(models => this.models = models);
  }
}

这些与以下API服务进行了对话:

class ApiService {
  private models: Observable<Model[]>;

  getAll(): Observable<Model[]> {
    if (!this.models) {
      this.models = this.http.get(URL)
                        .map((res: Response) => res.json())
                        .publishReplay(1)
                        .refCount()
    }
    return this.models;
  }

  create(name: string) {
    const Observable<Model> = this.http.post(URL, {name: name});
    // What should be done here with the new model
  }

  update(model: Model) {
    // And here
  }

  delete(model: Model) {
    // And here
  }
}

1 个答案:

答案 0 :(得分:3)

您应该将发送/接收的数据的本地值保留到后端并相应地进行更新。然后将值发布给观察者。一个简单的解决方案是使用BehaviorSubject:

class ApiService {
    public static URL = 'test.com/api/resource';

    private models = new Array<Model>();
    private cache = new BehaviorSubject<Array<Model>>(this.models);
    constructor(private http: Http) { }

    getAll(): Observable<Model[]> {
        if (this.models.length === 0) {
            this.http.get(ApiService.URL).map(res => res.json())
                .publishReplay(1)
                .refCount().subscribe(value => {
                // update the local value
                this.models = value;
                // publish update to observers
                this.cache.next(this.models);
            }, this._handleError);
        }
        return this.cache;
    }

    create(name: string) {
        this.http.post(ApiService.URL, { name: name }).map(res => res.json()).subscribe(data => {
            this.models.push(data);
            this.cache.next(this.models);
        }, this._handleError);
    }

    update(model: Model) {
        this.http.patch(ApiService.URL, {data: model}).map(res => res.json()).subscribe(data => {
            // update the value in models
            const idxToUpdate = this.models.findIndex(value => value.id === model.id);
            this.models[idxToUpdate] = model;
            this.cache.next(this.models);
        }, this._handleError);
    }

    delete(model: Model) {
        this.http.delete(ApiService.URL + '/' + model.id).map(res => res.json()).subscribe(data => {
            // delete value from models
            const idxToUpdate = this.models.findIndex(value => value.id === model.id);
            this.models.splice(idxToUpdate, 1);
            this.cache.next(this.models);
        }, this._handleError);
    }

    private _handleError(error: any) {
        this.cache.error(error);
    }

}