Angular2 Observable - 如何包装第三方 ajax 调用

Angular2 Observable - how to wrap a third party ajax call

我正在使用 Google 的地方 api - getPlacePredictions.

这是我在输入按键事件中的代码:

我的模板:

<input type="text" (keyup)='search()'>
<div *ngIf="searching">Searching ... </div>

我的Class:

private autocomplete;

ngAfterViewInit () {
    this.autocomplete = new google.maps.places.AutocompleteService();
}

search(){
    this.searching = true;
    this
    .autocomplete
    .getPlacePredictions( option , ( places , m )=> {
        console.log( 'onPrediction' , places ); 
        this.searching = false;
    } ); 
}

是否有任何可行的方法将 getPlacePredictions 包装在 rxjs 可观察对象中,以便我可以利用订阅此函数?

我最终想在这里做的是创建一个可见和不可见的加载图标,但我想我无法用 google 的 api 本身正确地制作它如果我可以将它包装在一个 Observable 中,它会变得容易。

您可以在包装第 3 方 ajax 调用的 Angular 服务中创建 RxJS 主题。例如:

@Injectable()
export class PredictionService {
  public Prediction: rx.Subject();
  private autocompleteService: new google.maps....
  constructor() { 
  this.Prediction = new rx.Subject();
  }

  getPredictions(options: any) {
    this.autocompleteService.getPlacesPrediction(options,(places, m)=>{
      this.Prediction.onNext(places); // pass appropriate predictions
   });        
  }    
}

然后您可以通过调用服务方法来请求数据,并通过订阅 RxJS Subject 获得响应。

@Component() //configuration avoided for brevity
class Component 
{
 constructor(private PredictionService) {
 this.PredictionService.Prediction.subscribe((placesResult)=>{
   ... //This is where you get your data.
 });
  }

  search(){
   this.PredictionService.getPredictions(options);
  }
}

在订阅 Observable 的函数中,您可以切换加载图像的可见性。

您可以通过这种方式将对 getPlacePredictions 方法的调用包装在原始可观察对象中:

search(option) {
  return Observable.create((observer) => {
    this.autocomplete
      .getPlacePredictions( option , ( places , m )=> {
        observer.next(places);
      }); 
  });
}

那么您就可以订阅了:

this.searching = true;
this.search(option).subscribe(places => {
  this.searching = false;
  this.places = places;
});

从以后的 Angular 版本开始

使用:

return new Observable((observer) => {
  this.autocomplete
    .getPlacePredictions( option , ( places , m )=> {
       observer.next(places);
     }); 
  });
}