【问题标题】:Subscription to Observable订阅 Observable
【发布时间】:2018-08-13 12:16:21
【问题描述】:

我有一个 Angular 应用程序,我使用 HttpClient 从 API 检索数据。

我想从 API 获取原始数据并将它们发送到相应的服务。这些服务具有将原始数据映射到模型对象并将它们返回给组件的方法。

问题是,我从 API 获取数据(返回 Observable),我订阅了服务方法,然后我不知道如何将数据传递给组件。

我从 API 检索数据的 API 服务。然后我发送原始数据和酒店服务,我想将原始数据映射到模型并发送到组件

@Injectable()
export class ApiService {
  ...
  public getHotelById(hotelId: number): Observable<any> {
      return this.http
          .get(API_URL + '/hotel/' + hotelId)
          .map((response) => {
              return response;
          })
  }
  ...
}


@Injectable()
export class HotelService {
  ...
  public getHotelById(id: number): Subscription {
    return this.api.getHotelById(id).subscribe(
        (response) => {
            let hotel = new HotelModel(response.hotel);

            hotel.mapCountry(response.country);

            return hotel;
        }
    );
  }
  ...
}

谁能帮助我如何从组件中的服务中检索数据?我收到酒店服务返回的对象是订阅的错误,我无法订阅它。

有什么方法可以做到这一点吗?我不想在 API 服务中做一些业务逻辑。在那个地方我只想检索数据。

组件方法

  ngOnInit() {
    this.activatedRoute.queryParamMap.subscribe(
        (map) => {
            this.hotelId = this.activatedRoute.snapshot.params['id'];

            this.hotel = this.hotelService.getHotelById(this.hotelId)
                .subscribe(
                (hotel) => {
                  this.hotel = hotel;
                }
            )
        }
    )
  }

【问题讨论】:

    标签: angular typescript rxjs angular-cli


    【解决方案1】:

    map您的回复,而不是订阅它。订阅是“路的尽头”,而映射只是“变道”。

    export class HotelService {
      ...
      public getHotelById(id: number) {
        return this.api.getHotelById(id).pipe(map(
            (response) => {
                let hotel = new HotelModel(response.hotel);
    
                hotel.mapCountry(response.country);
    
                return hotel;
            }
        ));
      }
      ...
    }
    

    【讨论】:

    • @John 也不要忘记为最新的 rxjs 版本使用管道。
    • @AmitChigadani map 操作员需要管道?
    • 嗯,我担心这个错误stackoverflow.com/questions/50192815/…
    • 闪电战测试过,确实不行?我正在编辑我的答案,谢谢
    • @John 只有rxjs 的最新版本才需要,旧版本不需要。
    【解决方案2】:

    我认为对你来说一个好方法是将你的结果映射到特定的函数“getHotelById”(你做一个 ORM 之类的)

    @Injectable()
    export class ApiService {
      ...
      public getHotelById(hotelId: number): Observable<any> {
          return this.http
              .get(API_URL + '/hotel/' + hotelId)
              .map((response) => {
                let hotel = new HotelModel(response.hotel);
    
                hotel.mapCountry(response.country);
    
                return hotel;
              })
      }
      ...
    }
    
    
    @Injectable()
    export class HotelService {
      ...
      public getHotelById(id: number): Observable<any> {
        return this.api.getHotelById(id);
      }
      ...
    }
    

    在您的组件中没有任何变化。

    【讨论】:

      【解决方案3】:

      你真的需要两种服务吗?

      @Injectable()
      export class HotelService extends AbstractHttpService {
      
        constructor (
          private httpClient: HttpClient,
        ) {
          super();
        }
      
        loadHotels(): Observable<Hotel[]> {
          const url = this.url('hotels');
      
          return this.httpClient.get<Hotel[]>(url, this.standardHttpOptions);
        }
      }
      

      抽象类有一些用于查询目标 URL 的助手,并为 get 调用提供标准的 http 选项。

      【讨论】:

        猜你喜欢
        • 2019-12-29
        • 1970-01-01
        • 2023-04-02
        • 2018-08-28
        • 2017-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多