【问题标题】:How to map an angular 2 class from an http call如何从 http 调用映射 Angular 2 类
【发布时间】: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 类型的数组,那么如果我删除了该类的任何属性,我不应该在我的组件中自动看到它,但事实并非如此......

标签: json angular observable


【解决方案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;
}

您可以阅读有关此问题的更多信息 herehere

【讨论】:

  • 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);
          });
        }
      });
  }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    相关资源
    最近更新 更多