如何从 http 调用映射 Angular 2 类

Posted

技术标签:

【中文标题】如何从 http 调用映射 Angular 2 类【英文标题】:How to map an angular 2 class from an http call 【发布时间】:2018-08-30 08:56:32 【问题描述】:

我是 Angular 的新手。 我有一个名为 User 的类:

export class User 
  private id: number;
  private name: string;
  private surname: string;

  get Id(): number 
    return this.id;
  
  set Id(newId: number) 
    this.id = newId;
  

  get Name(): string 
    return this.name;
  
  set Name(newName: string) 
    this.name = newName;
  

  get Surname(): string 
    return this.surname;
  
  set Surname(newSurname: string) 
    this.surname = newSurname;
  

...检索用户数组的函数:

  getValues() 
    this.usersService.getUsers()
      .subscribe((users: User[]) => this.dataSource = users);
  

以及从后端 WebApi 检索用户数组的方法:

getUsers(): Observable<User[]> 
    return this.http.get<User[]>(this.usersSearchUrl)
      .pipe(
      tap(users => this.log(`fetched users`)),
      catchError(this.handleError('getUsers', []))
      );
  

终于从webapi返回的json:

["id":"1","name":"Alberico","surname":"Gauss","id":"2","name":"Anassimandro","surname":"Dirac","id":"3","name":"Antongiulio","surname":"Poisson"]

我原以为调用会自动映射 User 类,而不是它只给我一个 User 类型的数组,事实上如果我在我的组件中写一些东西 .subscribe((utenti: Utente[]) => 控制台.log(utenti[0].Surname));控制台写给我“未定义”。你能告诉我哪里错了吗?谢谢

【问题讨论】:

你用的是Http模块还是HttpClient模块? @mast3rd3mon HttpClient,因为他键入了呼叫。 我只是在问题状态为 angular 2 时才问,但 http 客户端出现在 angular 4 中 通过“Angular 2”,OP 的意思是“Angular”。我一直这样做。 我正在使用 HttpClient。抱歉,如果调用确实返回给我一个 User 类型的数组,那么如果我删除了该类的任何属性,我不应该在我的组件中自动看到它,但事实并非如此...... 【参考方案1】:

正如预期的那样,您正在从后端检索 JSON。 javascript(或打字稿)类不是一回事。

当 JSON 返回时,它可以在 Javascript 中自动转换为一个简单的 JSON 对象,但它不会包含所有的 getter 和 setter。所以这些类方法不可用,这就是你得到 undefined 的原因。

删除所有的 getter 和 setter 并添加一个构造函数。然后你可以直接调用 Surname 作为属性,它会返回值(因为它只是一个普通的 JSON 对象)。

export class User 
  constructor() 
  

  public id: number;
  public name: string;
  public surname: string;

或者不使用构造函数,直接声明属性:

export class User     
  public id: number;
  public name: string;
  public surname: string;

或者你也可以使用接口:

export interface User    
  id: number;
  name: string;
  surname: string;

您可以阅读有关此问题的更多信息 here 和 here。

【讨论】:

1) 您不能在接口上的字段上指定访问修饰符。 2) 就您的示例而言,最好也删除类成员上的 private 访问修饰符,否则您将永远无法从外部访问它们,这是您描述的 OP 应该做的。 查看我的最后更改,您不能在接口的成员上放置访问修饰符。一个接口代表一个合同,合同中的任何内容都不能标记为私有,否则有什么意义。如果您确实在接口的成员上放置了访问修饰符,则打字稿转译器将显示错误。现在一切看起来都不错(我 +1)。 @Igot 再次感谢...在其他地方太忙了,无法给予我应有的关注。【参考方案2】:

我认为在组件 ts 中使用这样的代码:

 users: User[];
  constructor(
    private us: usersService,
    public auths: AuthService
  )

    this.us.getUsers.subscribe(
      users=> 
        this.users= users.map((user) => 
          return new User(user);
        );
      
    );

在服役中我想写:

  public getUsers(): Observable<User[]> 

    let headers = new Headers();
    headers.append('x-access-token', this.auth.getCurrentUser().token);

    return this.http.get(Api.getUrl(Api.URLS.getUsers), 
      headers: headers
    )
      .map((response: Response) => 
        let res = response.json();

        if (res.StatusCode === 1) 
          this.auth.logout();
         else 
          return res.StatusDescription.map(user=> 
            return new User(user);
          );
        
      );
  

对我来说,这个逻辑很完美。我希望能帮助你处理这段代码

【讨论】:

以上是关于如何从 http 调用映射 Angular 2 类的主要内容,如果未能解决你的问题,请参考以下文章

无法获得在 Angular 2 代码中映射的正确 http 响应

Angular:将字符串数组映射到http get调用中的枚举值数组

如何从Angular 6中的另一个类调用类中的函数?

Angular httpClient 将响应映射到具有行为的实体

使用 Angular 2 Http 从 REST Web 服务获取数据

如何在 Angular 7 的激活链接中获取 url 参数并从服务类调用 rest api