Angular 2 сопоставление HTTP-ответа на экземпляр класса

Мне интересно, как лучше всего отобразить ответ HTTP от запроса get к классу вместо базового объекта Javascript.

В моей текущей попытке я просто делаю new ClassName(data), но может быть неясное Angular указать и полностью устранить способ сделать это, что я не знаю.

Вот мой текущий код:

getPost(id:number){
    return this._http.get(this._postsUrl+'/'+id)
                .map(res => new Post(res.json().data))
                .do(data => console.log(data))
                .catch(this.handleError);
}

Мне нужно, чтобы Post был классом, а не просто интерфейсом, потому что у меня есть методы внутри.

Я следил за HeroTutorial и http "руководство разработчика" и в их методе getHeroes:

getHeroes () {
return this.http.get(this._heroesUrl)
                .map(res => <Hero[]> res.json().data)
                .catch(this.handleError);
}

Я как-то ожидал, что часть <Hero[]> сделает именно это: возьмите класс Hero и создайте его новые экземпляры, но мои тесты показывают, что это не так, это просто для Typescript, чтобы знать, что ожидать.

Любые идеи? Спасибо!

Ответ 1

Я думаю, что вы можете использовать метод map для объектов JavaScript:

getHeroes () {
  return this.http.get(this._heroesUrl)
            .map(res => {
               return res.json().data.map((elt) => {
                 // Use elt to create an instance of Hero
                 return new Hero(...);
               });
             })
            .catch(this.handleError);
}

Ответ 2

Установив прототип на возвращаемом объекте, я смог получить экземпляр моего класса.

getHero () {
      return this.http.get(this._heroUrl)
            .map(response => {
                    let res = <Hero> response.json();
                    Object.setPrototypeOf(res, Hero.prototype);
                    return res;
                   })
            .catch(this.handleError);
}

Мой класс был очень прост с конструктором без параметров, поэтому это сработало для меня. Для более сложных классов я не знаю, будет ли это работать.

Примечание: приведенный выше код для getHero() не getHeroes(). Я бы предположил, что я мог бы сделать то же самое со списком, установив прототип для каждого элемента массива, но я не пробовал/не подтвердил это.

Ссылка: у меня появилась идея от этого сообщения от BMiner

Ответ 3

Хорошей практикой является использование данных из ответа GET с использованием

Observable<Model>

(относительно Angular документации https://angular.io/guide/http) Итак...

//импорт

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

//в списке параметров конструктора

private http: HttpClient

//метод службы

getHeroes(): Observable<Hero[]> {return this.http.get<Hero[]>({url}, {options});}

Вам больше не нужно ничего делать. Я считаю этот подход наиболее дружелюбным.