Angular2从JSON解析到对象

Ben*_*Ben 8 json casting object angular

我正在尝试找到将json对象转换为Typescript对象的最佳方法.我有一个http get服务,它返回一个用户列表.我当前的版本工作,我已经从JSON函数添加到我的所有模型类,以使映射工作:

export class User {

    constructor(
        public pk: number,
        public username: string,
        public first_name: string,
        public last_name: string,
        public email: string,
        public profile: UserProfile, ) {
    }

    static fromJSON(json: any): User {
        let user = Object.create(User.prototype);
        Object.assign(user, json);
        user.profile = UserProfile.fromJSON(json.profile);
        return user;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用.但是我在角度2文档中没有得到一些东西.在英雄教程中,JSON以这种方式自动转换为对象:

  getHeroes (): Observable<Hero[]> {
    return this.http.get(this.heroesUrl)
                    .map(this.extractData)
                    .catch(this.handleError);
  }
  private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
  }
Run Code Online (Sandbox Code Playgroud)

我无法让这种方法适用于我的情况,我说这body.data是未定义的.这种方法真的有效吗?

编辑:

我的http服务不返回用户数组.它返回一个页面,其中包含"results"属性中的一组用户.

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "pk": 48,
      "first_name": "Jon",
      "last_name": "Does",
      "profile": {
        "pk": 46,
        "gender": "U"
      }
    },
    {
      "pk": 47,
      "first_name": "Pablo",
      "last_name": "Escobar",
      "profile": {
        "pk": 45,
        "gender": "M"
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的服务代码:

 private extractData(res: Response) {
    let body = res.json().results;
    return body || {}; //<--- not wrapped with data
  }

  search(authUser: AuthUser, terms: string): Observable<User[]> {
    let headers = new Headers({
      'Content-Type': 'application/json',
      'X-CSRFToken': this.cookiesService.csrftoken,
      'Authorization': `Token ${authUser.token}`
    });
    let options = new RequestOptions({ headers: headers });
    return this.http.get(environment.server_url + 'user/?search=' + terms, options)
      .map(this.extractData);
    // .map((response: Response) => response.json());
  }
Run Code Online (Sandbox Code Playgroud)

我的搜索组件代码:

 onSearch(terms: string) {    
    this.searchService.search(this.user, terms).subscribe(
      response => {       
          console.log(response); // Return array of object instead of array of user
      },
      error => {
          console.log(JSON.stringify(error));
      },
      () => { }
    );
 }
Run Code Online (Sandbox Code Playgroud)

编辑2:

为了简化这个案例,我写了这个简单的代码:

  test(){
    let json_text=` [
      {
        "id": 1,
        "text": "Jon Doe"
      },
      {
        "id": 1,
        "text": "Pablo Escobar"
      }
    ]`;

    console.log(<MyObject[]>JSON.parse(json_text)); // Array of objects
    console.log(MyObject.fromJSON(JSON.parse(json_text))); // Array of 'MyObject'
  }



export class MyObject{
  id: number;
  text: string;

   static fromJSON(json: any): MyObject {
        let object = Object.create(MyObject.prototype);
        Object.assign(object, json);
        return object;
    }
}
Run Code Online (Sandbox Code Playgroud)
  • console.log(<MyObject[]>JSON.parse(json_text)) 返回一个对象列表
  • console.log(MyObject.fromJSON(JSON.parse(json_text))) 返回MyObject列表

Sef*_*efa 3

这是因为在 Angular 教程中,json 位于 data 属性中。

正如教程中所述

不要对服务器 API 做出任何假设。并非所有服务器都返回具有数据属性的对象。

如果你没有用任何属性包装你的 json,你可以使用

private extractData(res: Response) {
  let body = res.json();
  return body || { }; //<--- not wrapped with data
}
Run Code Online (Sandbox Code Playgroud)

更新:

元件代码

 onSearch(terms: string) {    
    this.searchService.search(this.user, terms).subscribe(
      (response: SearchResponse) => {    // <--- cast here   
          console.log(response); 
      },
      error => {
          console.log(JSON.stringify(error));
      },
      () => { }
    );
 }
Run Code Online (Sandbox Code Playgroud)