繁体   English   中英

angular2 地图数据作为特定对象类型

[英]angular2 map data as specific object type

我基于 Angular2 教程创建了一个非常简单的应用程序。

首先,我有一个非常简单的“Book”模型:

 /**
 * book model
 */
export class Book {
    public data;

    /**
     * constructor
     * @param id
     * @param title
     * @param pages
     */
    constructor(
        public id,
        public title:string,
        public pages:Array
    ){
        alert('it works'); // just a check
    }
}

在我的服务中,我得到了这样一本书:

return this._http.get('getBook/1')
        .map(function(res){
            return <Book> res.json();
        })

我的期望是这将获得生成的 JSON 数据并将其“映射”到 Book 对象。

但是,它只返回一个类型为“Object”的对象。

我可以自己创建一个新的 Book 对象并在构造函数中传递参数,如下所示:

return new Book(res.id, res.title, res.pages);

这是最好的方法吗? 我错过了什么吗?

是的,在 TypeScript 中将对象转换为类型不会创建此类型的实例。 它只是 TypeScript 用于类型检查的工具。

如果你真的想要一个Book的实例,你需要使用这样的东西:

return this._http.get('getBook/1')
    .map(function(res){
        var data = res.json();
        return new Book(data.id, data.title, data.pages);
    })

回答你的问题 事实上,如果您的类型中只有字段(例如带有接口),则强制转换就足够了。 此外,如果您有稍后要使用的方法,则有必要隐式创建Book类型的实例(见上文)而不是强制转换。 否则您将无法使用它们(它们将在您的对象上未定义)...

有关更多详细信息,请参阅此问题:

我认为你应该声明一个接口Book而不是 class book

export interface Book {
    public id;
    public title:string;
    public pages:Array;
}

在您的服务中:

//get one record
return this._http.get('getBook/1')
        .map(function(res){
            return <Book> res.json();
        });

//get multi record
return this._http.get('getBooks')
        .map(function(res){
            return <Book> res.json();
        });

好的做法是使用来自 GET 响应的数据

Observable<Model>

(关于 Angular 文档https://angular.io/guide/http )然后:

// 进口

import {HttpClient} from "@angular/common/http";

// 在构造函数参数列表中

private http: HttpClient

// 服务方法

getBook(): Observable<Book> {return this.http.get<Book>({url}, {options});}

来自https://angular.io/guide/http#requesting-a-typed-response

要指定响应对象类型,首先定义一个具有所需属性的接口。 使用接口而不是类,因为响应是一个无法自动转换为类实例的普通对象。

总是使用接口接收响应,因为唯一发生的事情是映射字段,如果您有实例函数,当您使用该对象时会抛出错误,则不能使用类。

product.getPrice is not a function

示例

interface ProductInterface {
  id: number;
  name: string;
  price: number;
}

class Product implements ProductInterface {
  id: number;
  name: string;
  price: number;
  
  constructor(productData: ProductInterface) {
    this.id = product.id;
    this.name = product.name;
    this.price = product.price;
  }
  
  public getPrice(): string {
    return this.price + " INR";
  }
}
class ProducService {
  ...
  ...


  getProduct(): Observable<Product> {
    return this.http.get<Product>('assets/product.json').pipe(map(data => new Product(data))); 
  }

  getProductWithoutMappingToClass(): Observable<Product> {
    return this.http.get<Product>('assets/product.json');
  } // Throw runtimerror ctx_r1.product.getPrice is not a function
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM