若是對 RxJS 的 operators (操做符) 不熟悉的話,建議讀者在閱讀本文時,先閱讀 RxJS - Observables, observers 和 operators 簡介 這篇文章。javascript
Operator 是一個函數,它接收一個 Observable 對象,而後返回一個新的 Observable 對象。當咱們訂閱新返回的 Observable 對象時,它內部會自動訂閱前一個 Observable 對象。java
比較常見的有如下三種方式:git
1.使用 ES7 函數綁定運算符 ::
(可以使用 BabelJS 進行轉換)github
someObservable::mySimpleOperator(x => x + '!');
2.繼承 Observable 類,並重寫 lift()
方法typescript
class MyObservable extends Observable { lift(operator) { const observable = new MyObservable(); //<-- important part here observable.source = this; observable.operator = operator; return observable; } // put it here .. or .. customOperator() { /* do things and return an Observable */ } } // ... put it here... MyObservable.prototype.mySimpleOperator = mySimpleOperator;
3.直接添加到 Observable.prototype
對象上json
Observable.prototype.mySimpleOperator = mySimpleOperator; someObservable.mySimpleOperator(x => x + '!');
當咱們使用 Angular HTTP 服務時,咱們須要調用 Response 對象的 json()
方法把服務端接口返回的數據,轉換爲 JSON 對象,例如:bootstrap
this.http.get('https://api.github.com/orgs/angular/members?page=1&per_page=5') .map(res => res.json());
對於每一個接口,咱們都須要調用 map 操做符對返回的數據作對應的處理。那能不能簡化這個操做呢?答案是有的,咱們能夠經過自定義一個 toJSON 操做符來簡化上述的過程。具體實現以下:segmentfault
function toJSON<T>(): Observable<T> { return this.map(( response : Response ) => response.json()); }
上面代碼中,this
指向源 Observable 對象,即調用 http 對象的 get()
方法後返回的 Observable 對象。此外咱們直接返回了調用 map()
操做符後新建的 Observable 對象。api
爲了可以使用咱們自定義的 toJSON
操做符,咱們須要把它添加到 Observable 的原型對象上:babel
Observable.prototype.toJSON = toJSON;
最後的一件事是咱們須要添加如下的定義:
declare module "rxjs/Observable" { interface Observable<T> { toJSON : typeof toJSON; } }
import { Observable } from 'rxjs/Observable'; function toJSON<T>(): Observable<T> { return this.map(( response : Response ) => response.json()); } Observable.prototype.toJSON = toJSON;
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpModule } from "@angular/http"; import { AppComponent } from './app.component'; import './custom-operators'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
import { Observable } from 'rxjs/Observable'; import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; interface Member { id: string; login: string; avatar_url: string; } @Component({ selector: 'app-root', template: ` <h3>Angular Orgs Members</h3> <ul *ngIf="members"> <li *ngFor="let member of members;"> <p> <img [src]="member.avatar_url" width="48" height="48"/> ID:<span>{{member.id}}</span> Name: <span>{{member.login}}</span> </p> </li> </ul> ` }) export class AppComponent implements OnInit { members: Member[]; constructor(private http: Http) { } ngOnInit() { this.http.get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`) .toJSON<Member[]>() // 使用自定義 toJSON 操做符 .subscribe(data => { if (data) this.members = data; }); } }
// src/typings.d.ts (在該文件下,新增如下內容) export declare function toJSON<T>(): Observable<T>; declare module "rxjs/Observable" { interface Observable<T> { toJSON : typeof toJSON; } }