从类型“ any”转换为Object

时间:2019-02-19 00:50:51

标签: angular typescript rxjs angular7

我正在尝试从在线课程中学习Angular,但是该课程使用的是Angular的较旧版本,直到现在我已经能够适应Angualar 7,但现在却陷入了这个问题:

他在组件中定义了any类型的Vehicle对象,并使用api设置了其值,如下所示:

"vehicle: any = {
  features: [],
  contact: {}
};"

ngOnInit() {

      var sources =[]; //I omitted the other properties

    if(this.vehicle.id)    
      sources.push(this.vehicleService.getVehicle(this.vehicle.id));

    forkJoin(sources).subscribe(data => {
          if (this.vehicle.id)
             this.Vehicle= data[0];
});

API代码:

  getMakes() {
    return this.http.get('/api/makes')
      .map(res => res.json());
  }

由于我使用的是Angular 7,因此我将API代码更改为:

  getVehicle(id){
    return this.http.get<any>('api/vehicles/'+id);
  }

它就像一个魅力。但是现在它更改了代码以使用模型(例如api中使用的模型的副本),如下所示:

    vehicle: SaveVehicle = {
    id:0,
    makeId: 0,
    modelId: 0,
    isRegistered: false,
    features: [],
    contact: {
      name: '',
      email: '',
      phone: '',
    }
  };


ngOnInit() {

    var sources =[]; //I omitted the other properties

    if(this.vehicle.id)    
      sources.push(this.vehicleService.getVehicle(this.vehicle.id));

    forkJoin(sources).subscribe(data => {

          if (this.vehicle.id)
             this.setVehicle(data[0]);
});


    private setVehicle(vehicle: Vehicle) {
        this.vehicle.id = vehicle.id;
        this.vehicle.makeId = vehicle.make.id;
        this.vehicle.modelId = vehicle.model.id;
        this.vehicle.isRegistered = vehicle.isRegistered;
        this.vehicle.contact = vehicle.contact;
        this.vehicle.features = _.pluck(vehicle.features,'id');   
      }

当我更改此行的方法

this.setVehicle(data[0]);

引发异常:

类型“ any []”的参数不能分配给类型“ Vehicle”的参数。   类型“ any []”缺少类型“ Vehicle”中的以下属性:id,model,make,isRegistered和另外3个。

我将API调用的返回类型更改为Vehicle,它确实可以工作,但是后来我无法再使用 sources 数组,因为数组中的其他Observables具有不同的类型。我应该使用任何作为api调用的返回值吗?在将返回类型更改为Vehicles时,有没有办法保留源数组?我可以从“任何”投射到车辆吗?

一个问题:我在这里应该做什么?

1 个答案:

答案 0 :(得分:0)

假设您具有以下(或类似的)“车辆”界面:

export interface Vehicle {
  id: number;
  makeId: number;
  modelId: number;
  isRegistered: boolean;
  features: [];
  contact: {};
}

按如下所示更改get方法:

constructor(private http: HttpClient) { }

getVehicle(id){
  return this.http.get<Vehicle>('api/vehicles/'+id);
}

getVehicles(){
  return this.http.get<Vehicle[]>('api/vehicles');
}

这会将响应映射为单个车辆或车辆阵列的形状。

请务必使用httpClient(4.3版的新功能),而不要使用旧的http

此外,您实际上不需要这样的代码:

private setVehicle(vehicle: Vehicle) {
    this.vehicle.id = vehicle.id;
    this.vehicle.makeId = vehicle.make.id;
    this.vehicle.modelId = vehicle.model.id;
    this.vehicle.isRegistered = vehicle.isRegistered;
    this.vehicle.contact = vehicle.contact;
    this.vehicle.features = _.pluck(vehicle.features,'id');   
  }

定义模型,使其与响应中的形状和名称匹配。

或者,将数据从一个结构映射到http.get中的另一个结构:

getVehicle(id): Observable<Vehicle> {
  return this.http.get<any>('api/vehicles/'+id).pipe(
    map(v => ({                       
       id: v.id,
       makeId: v.make.id,
       modelId: v.model.id,
       isRegistered: v.isRegistered,
       contract: v.contract;
       features: _.pluck(v.features,'id')
    })
  );
}

上面的方法将传入的响应(定义为类型any)映射到接口定义的Vehicle。

注意:上面的映射未经过语法检查!

另外请注意:在此处的花括号周围必须加上括号:

v => ( { 
   ... 
})

否则编译器会认为我们正在定义一个语句块,而不是返回的对象文字。