代码之家  ›  专栏  ›  技术社区  ›  Muskett

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

  •  0
  • Muskett  · 技术社区  · 7 年前

    我最近开始尝试使用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常量,以及如何指定要为每个请求获取的数据段?然后,我需要用下面的代码将其提供给一个地址模型,但我还是有点不清楚如何将拉取的数据推送到这里。

    export class Address {
      id: number;
      name: string;
      address: {
        street?: string,
        suite?: string,
        city?: string,
        zipcode?: string
      };
    }
    
    3 回复  |  直到 7 年前
        1
  •  0
  •   Alexander Staroselsky    7 年前

    这有点难以回答,因为关于JSON的结构、数据的结构以及您希望使用每个插入的方法检索哪些数据的信息很少 AddressService .

    访问公共属性的一个选项是只使用类属性,例如 readonly 一个是在AddressService上,您可以使用 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}`);
        }
    }
    

    在将结果映射到类型/模型方面,例如 Address 就你而言,你可以 typecheck the response 具有 HttpClient 具体如下:

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

    否则,您可以使用rjxs map 操作员将响应转换为 住址 上课前根据需要输入/型号 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文件 地址服务 ,您将要将文件添加到 assets 的数组属性 angular-cli.json .

    希望这有帮助!

        2
  •  0
  •   andrey.shedko    7 年前

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

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

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

        3
  •  0
  •   Liviu Ilea    7 年前

    据我所知,您正在询问如何将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 从JSON到类型的属性(MyResponse.data) <T> .

    为了使其适应您的用例,您的服务中应该有这样的smth:

    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 . 您不需要指定完整路径。

    下面是一个帖子的例子:

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

    注意事项 :以上代码是从实际生产代码改编而来的。我没有测试过,可能会有拼写错误。

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