Angular2将JSON数据添加到单页面应用程序

时间:2018-01-26 15:55:21

标签: angular angular2-services angular-services

我最近开始尝试使用Angular 2,并且一直试图将JSON数据添加到服务中。我已经浏览了官方教程和有关HTTP请求的文档,但似乎无法实现这一点。该服务的基本代码如下 -

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Address } from './models/address';


const AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';

@Injectable()
export class AddressService {

  constructor(private http: HttpClient) { }

  getAll(): Observable<Address[]> {
    throw new Error('NOT IMPLEMENTED');
  }

  get(id: number): Address {
    throw new Error('NOT IMPLEMENTED');
  }

  insert(addr: Address) {
    throw new Error('NOT IMPLEMENTED');
  }

  remove(id: number) {
    throw new Error('NOT IMPLEMENTED');
  }

如何在每个类方法中访问AddressEndpoint const,以及如何针对每个请求确定我想要哪个数据块?然后,我需要使用以下代码将其提供给地址模型,并且我再次对我如何在此处推送我的数据进行了一些不清楚。

export class Address {
  id: number;
  name: string;
  address: {
    street?: string,
    suite?: string,
    city?: string,
    zipcode?: string
  };
}

3 个答案:

答案 0 :(得分:0)

我建议将您的端点地址保存在单独的文件中(以及其他常量之类),如下所示:

export const endPointAddress = "http://youraddress".

然后你可以导入这个const并一如既往地使用。 在真实世界的应用程序中,您将创建具有两个字段的类 - 一个用于开发环境的端点,另一个用于生产或阶段。

答案 1 :(得分:0)

由于关于JSON结构,数据结构如何以及您期望使用AddressService中存根的每种方法检索哪些数据的信息很少,因此有点难以回答。

访问公共属性的一个选项是在AddressService上使用类属性(例如readonly),您可以使用this中的任何一个AddressService访问该值。 1}}类方法:

@Injectable()
export class AddressService {
    readonly AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';

    constructor(private http: HttpClient) { }

    get(id: number): Observable<Address> {
        return this.http.get(`${this.AddressEndpoint}/${id}`);
    }
}

在将结果映射到类型/模型方面,例如Address,您可typecheck the response使用HttpClient,如下所示:

get(id: number): Observable<Address> {
    return this.http.get<Address>(`${this.AddressEndpoint}/${id}`);
}

否则,您可以使用rjxs map运算符将响应转换为Address类型/模型,然后再将其转换为subscribe()类:

get(id: number): Observable<Address> {
    return this.http.get(`${this.AddressEndpoint}/${id}`).map(data => new Address(data['someProperty'], data['someOtherProperty']);
}

注意:如果您使用@ angular / cli并且将使用HttpClient执行类似get()之类的内容,并将AddressService放在此assets旁边的JSON文件中,您需要将文件添加到angular-cli.json的{​​{1}}数组属性。

希望这有帮助!

答案 2 :(得分:0)

据我所知,您询问如何将JSON发送到REST端点以及如何将Response中的数据检索到模型对象中。如果是这种情况,请继续阅读:)

以下是GET请求的示例实现:

/**
* Generic method that sends an HTTP GET request at the configured serviceUrl
* @returns {Observable<T>} - contains the converted data extracted from the response
*/
public get<T>(url: string): Observable<T[]> {

return this.httpClient.get<MyResponse<T[]>>(url, {observe: 'response'})
  .do(res => this.logResponse(res))
  .filter(res => res.status === 200)
  .map(res => res.body.data)
  .catch((error: HttpErrorResponse) => this.handleError(error));
}

调用类似this.httpClient.get<MyResponse<T[]>>的方法时,我们可以告诉httpClient我们希望响应属于MyReponse<T[]>类型。 MyResponse是描述响应的样子的模型,就像包装器一样:

/**
* Template class for the backend JSON response which looks like this:
* {
*    "data": <DATA_FROM_BACKEND>
* }
*/
export class MyResponse<T> {

  constructor(public data: T) {
  }

}

<T[]>是MyResponse包装的数据对象的类型。在你的情况下,它会像这样this.httpClient.get<MyResponse<Address[]>>,它将描述一个看起来像这样的JSON响应:

{
  "data": [
     {
      "id": 1,
      "name": "John Doe",
      "address": {
          "city": "NY",
          "street": "Wall Street",
          "suite": "string",
          "zipcode": "007"
      },
      {
      "id": 2,
      "name": "John Doe2",
      "address": {
          "city": "NY",
          "street": "Wall Street",
          "suite": "string",
          "zipcode": "007"
      }
    ]
}

{observe: 'response'}告诉HttpClient您要观察响应以便对整个响应对象进行操作并执行以下操作:

.filter(res => res.status === 200)
.map(res => res.body.data)

.map(res => res.body.data)这里我们将data属性(MyResponse.data)从JSON转换为<T>类型。

为了使其适应您的使用案例,您可能会在服务中看到这样的情况:

public get(url: string): Observable<Address[]> {

return this.httpClient.get<MyResponse<Address[]>>(url, {observe: 'response'})
  .do(res => this.logResponse(res))
  .filter(res => res.status === 200)
  .map(res => res.body.data)
  .catch((error: HttpErrorResponse) => this.handleError(error));
}

你会在你的组件中使用它,如下所示:

this.formService.get('/users').subscribe(address => {
    console.log(address);
  });

您的网址必须是/users。您不需要指定完整路径。

这是一个POST的例子:

public insert(url: string, entity: Address): Observable<number> {
let headers: HttpHeaders = new HttpHeaders()
  .set('Content-Type', 'application/json');

return this.httpClient.post<ImResponse<number>>(url, JSON.stringify(entity), {
  headers: headers,
  observe: 'response'
})
  .do(res => this.logResponse(res))
  .filter(response => response.status === 201)
  .map(response => response.body.data)
  .catch((error: HttpErrorResponse) => this.handleError(error));
}

并像这样使用它:

  let entity: Address = new Address();
 this.formService.insert('/users', entity).subscribe(id => {
    console.log(id);
  });

注意:上面的代码是对实际生产代码的改编。我没有测试它,可能包含错别字。

我希望这些例子可以帮助你实现其他方法。