通过map将类型(接口)转换为observable

时间:2018-04-03 09:59:31

标签: angular typescript observable

我一直在学习使用Angular的TypeScript。而目前我仍然坚持这一刻。以前我使用了订阅方法,一切都运行完美,但不是我决定使用异步管道重写代码,它只是不起作用....

  1. RestAPI以特定格式重新审核请求
  2. export interface responseFormat {
      success: boolean;
      data: any;
    }

    1. 返回的数据可以是不同的类型。在这种特殊情况下,数据返回餐馆对象......它也可能是不同对象的数组......
    2. export interface restaurant {
        _id: string;
        name: string;
        description: string;
        images: file[];
        cuisines: cuisine[];
        blocked: boolean;
        created: Date;
        business_hours: object;
      }

      1. 以前我使用过以下代码(可行):
      2. /* Provider */
        
        getRestaurant(): Observable<responseFormat> {
          return this.http.get<responseFormat>(environment.api + "/restaurant");
        }
        
        /* Component */
        
        private restaurant: restaurant;
        
        getRestaurant() {
          this.restaurantProvider.getRestaurant().subscribe(res => {
            if (res.success) this.restaurant = res.data;
          });
        }

        因此,变量的类型被赋值....但我不想保留订阅记录,因此我想使用Angular异步管道转换代码...这就是我所做的...... 它不起作用

        /* Provider */
        getRestaurant(): Observable<responseFormat> {
          return this.http.get<responseFormat>(environment.api + "/restaurant");
        }
        
        /* Component */
        private restaurantObservable: Observable<restaurant>;
        
        getRestaurant() {
          this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => <restaurant>res.data);
          // or //
          this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
        }

        但是上面的代码没有将响应的类型转换为接口......

        我做错了什么???

        换句话说,我可以在模板中使用https://angular.io/api/common/AsyncPipe&gt;获取Observable变量:

        /* Provider */
        getRestaurant(): Observable<responseFormat> {
          return this.http.get<responseFormat>(environment.api + "/restaurant");
        }
        
        /* Component */
        private restaurantObservable: Observable<restaurant>;
        
        getRestaurant() {
          this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
        }
        
        /* Template */
        <div class="name">{{ (restaurantObservable | async)?.name }}</div>
        // or //
        <div *ngIf="restaurantObservable | async as restaurant">
          <div>{{ restaurant.name }}</div>
        </div>

        但是我无法在组件中看到餐厅的属性...例如 this.restaurant.cuisines 抛出错误“属性观察不存在属性菜肴”

3 个答案:

答案 0 :(得分:4)

为什么不直接从您的服务中退回Observable<restaurant>

getRestaurant(): Observable<restaurant> {
  return this.http.get<responseFormat>(environment.api + "/restaurant")
    .map((response: responseFormat) => response.data as restaurant);
}

然后在组件方面:

getRestaurant() {
  this.restaurantProvider.getRestaurant().subscribe((res: restaurant) => {
    this.restaurant = res;
  });
}

可以通过HTTP Interceptor处理错误处理(success标记,HTTP错误等)。

答案 1 :(得分:1)

Angular异步模板管道订阅Observable,就是它能够在模板中访问餐馆对象及其属性。

如果您想在组件控制器中访问这些相同的东西,那么您需要在组件控制器中进行订阅。

答案 2 :(得分:0)

鉴于您的休息服务或提供者以这种格式返回餐厅(我总是使用课程而不是接口,抱歉,我无法提供任何有关这种区别的帮助,所以在我的示例中,餐厅是一个班级。)

export class Restaurant { 
    _id: string; 
    name: string; 
    description: 
    string; email: 
    { 
        address: string; 
        confirmation_code: string;
         confirmed: boolean; 
    }; 
    auth: { 
        password: string; 
    }; 
    branches: Branch[];
    menus: Menu[];
    images: File[];
    cuisines: Cuisine[];
    blocked: boolean;
    created: Date;
    business_hours: object; 
}

作为一个例子,您应该能够为您的响应进行角度序列化:

getRestaurant(): Observable<Restaurant> {
  return this.http.get<Restaurant>(environment.api + "/restaurant");
}

即使你也有一个也将其他类型的Branch,Menu,File,Cuisine导入到包含餐厅的打字稿文件中。例如,分支看起来像

export class Branch {
   // branches properties
}