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

Angular2 adding JSON data to single page app

我最近开始尝试使用 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');
  }

如何在每个 class 方法中访问 AddressEndpoint 常量,以及如何指定我想为每个请求获取哪条数据?然后,我需要使用以下代码将其提供给地址模型,但对于如何将提取的数据推送到此处,我还是有点不清楚。

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

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

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

然后你可以导入这个常量并像往常一样使用。 在现实世界的应用程序中,您将创建 class,它将有两个字段 - 一个用于开发环境的端点,另一个 - 用于生产或阶段。

这有点难以回答,因为关于 JSON 的结构、数据的结构方式以及您希望使用 AddressService 中存根的每个方法检索的数据的信息很少。

访问公共 属性 的一个选项是简单地使用 class 属性,例如 readonly,在 AddressService 上,您可以访问在任何 AddressService class 方法中使用 this 的值:

@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}`);
    }
}

在将结果映射到 type/model 方面,例如您的 Address,您可以 typecheck the responseHttpClient 如下:

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

否则,您可以根据需要利用 rjxs map 运算符将响应转换为 Address type/model,然后再将其转换为 class 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() 到 JSON 文件位于 AddressService 旁边,您需要将该文件添加到 angular-cli.json.

assets 数组 属性

希望对您有所帮助!

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

这是 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);
  });

你的 URL 必须是这样的 /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);
  });

注意:以上代码改编自实际生产代码。我没有测试过,可能有错别字。

我希望这些示例也能帮助您实现其他方法。