【问题标题】:Callback and observable in angular resolver角度解析器中的回调和可观察
【发布时间】:2018-12-21 18:26:41
【问题描述】:

我正在使用角度解析器为我的路线提供数据。对于其中一个,我需要获取给定地址字符串的经纬度。为此,我使用 google geocode api:

service.geocode({address: params.address}, results => {
  params.lat = results[0].geometry.location.lat();
  params.lon = results[0].geometry.location.lng();
});

所以在我的服务中,我需要在调用我的 apiService 之前等待回调触发,所以主要的想法是实现这一点:

search(params): Observable<Calendar[]> {    
    return service.geocode({address: params.address}, results => {
          params.lat = results[0].geometry.location.lat();
          params.lon = results[0].geometry.location.lng();
          return this.apiService.get('/api/v1/website/' + environment.web_id + '/calendar/_search', params)
          .pipe(map(
            data => {
              return data;
            }
          ));
    });
}

但我需要返回一个 Observable,所以这不起作用。 有没有办法获取地理编码回调的 observable,然后使用 rxJs 运算符链接它们?

谢谢!

【问题讨论】:

标签: angular callback rxjs observable


【解决方案1】:

当然有办法。最简单的步骤是将整个事物包装在一个 observable 中。一种天真的方法是这样做:

search(params): Observable<Calendar[]> {
  // First, an observable. We get the observer back.
  return Observable.create(observer => {
    // Now go call your service.geocode (whatever that might be)
    service.geocode({address: params.address}, results => {
      // extend your params with the extra information.
      params.lat = results[0].geometry.location.lat();
      params.lon = results[0].geometry.location.lng();

      // shot the http request
      this.apiService.get('/api/v1/website/' + environment.web_id + '/calendar/_search', params)
        .pipe(
          map(data) => {
            // When the data is back, resolve it.
            observer.next(data);
            observer.complete();
          }),
        );
    });
  });

现在,我们可能会做得更好,并从中提取部分内容。

/** Make just the non-observable part observable. Then we can simply add it to the chain */
getLatLon(address): Observable<{lat: any, lon: any}> {
  return Observable.create(observer => {
    service.geocode({address: params.address}, results => {
      // avoid side effects extra information.
      const lat = results[0].geometry.location.lat();
      const lon = results[0].geometry.location.lng();
        observer.next({ lat, lon });
        observer.complete();
  });
}
// Also

// Now you can use it in a regular chain.
search(params): Observable<Calendar[]> {
  return this.getLatLon(params)
    .pipe(
      map(coords => {
        // Again, we will avoid side effects.
        const fullParams = Object.assign({}, params, coords)
        return fullParams;
      }),
      map(fullParams => this.apiService.get(`/api/v1/website/${ environment.web_id }/calendar/_search`, params)),
    );
}

你可以更进一步,但这是基本的。

【讨论】:

    【解决方案2】:

    有多种方法可以实现这一点,(rxjs6)

    import { of } from 'rxjs';
    

    然后根据值创建可观察对象,如下所示:

    of(someValue);
    

    如果你直接返回 someValue 它将是一个普通数据,但是如果你使用 rxjs 中的 operator,你可以将该数据转换为 observable,并在需要的地方订阅它,请相应地修改你的代码,希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-20
      相关资源
      最近更新 更多