【问题标题】:Request with data converted to array of objects将数据转换为对象数组的请求
【发布时间】:2017-10-15 15:04:00
【问题描述】:

我正在执行请求,它正确地返回了一个 Observable,但是我想让这些返回的对象为 Setor 类型,我正在我的 ServiceBase 中执行一个通用方法,传递要通过返回的对象类型泛型。

Setor 类:

import { UUID } from 'angular2-uuid'

export class Setor {
    descricao: string;
    id: UUID;
}

setor.component.ts:

import { element } from 'protractor';
import { Component, OnInit } from '@angular/core';

import { SetorService } from './service/setor.service';
import { Setor } from "app/retaguarda/setor/model/setor";

@Component({
  selector: 'app-setor',
  templateUrl: './setor.component.html',
  styleUrls: ['./setor.component.css']
})

export class SetorComponent implements OnInit {

  setor: Setor;

  private setores: Setor[]; // Lista de setores

  constructor(public setorService: SetorService) {
  }

  ngOnInit() {
    this.setor = new Setor();
  }

  obterTodos(form) {
    let t = this.setorService.obterSetores().subscribe(setores => this.setores = setores);
      console.log(t);
  }
}

setor.service.ts:

import { Observable } from 'rxjs/Observable';
import { BaseService } from './../../../shared/service/base/base.service';
import { Injectable } from '@angular/core';
import { Setor } from "app/retaguarda/setor/model/setor";
import { Http } from "@angular/http";

@Injectable()
export class SetorService extends BaseService {

  uriApi: string = 'setor';

  constructor(httpService: Http) {
    super(httpService);
  }

  obterSetores(): Observable<Setor[]> {
    return this.obterTodos<Setor>('setor');
  }
}

base.service.ts:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Observable';

// Observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/throw';
import 'rxjs'

// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';

@Injectable()
export class BaseService {

  serviceUrl: string = 'http://localhost:5780/api/';
  headers: Headers;
  options: RequestOptions

  constructor(private httpService: Http) {
    this.headers = new Headers({
      'Content-Type': 'application/json',
      'Accept': 'q=0.8;application/json;q=0.9'
    });
    this.options = new RequestOptions({ headers: this.headers });
  }

  private getAll<T>(url: string): Observable<T[]> {
    return this.httpService
      .get(url)
      .map(res => res.json() as T[])
      .catch(this.handleError);
  }

  protected obterTodos<T>(url: string): Observable<T[]> {
    return this.getAll(this.serviceUrl + url);
  }

  private post<T>(url: string, data: T): Observable<T> {
    let jsonContent = JSON.stringify(data);
    return this.httpService
      .post(url, jsonContent, this.options)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData<T>(res: Response) {
    let body = res.json() as any;
    return body || {};
  }

  private handleError(error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg);
    return Observable.throw(errMsg);
  }
}

JSON 返回:

    [
        {
        "Descricao": "teste 1",
        "Id": "4b78ade1-39a1-11e7-a8f1-a41f72fdda5d"
        },
        {
        "Descricao": "teste 2",
        "Id": "4b7cb16f-39a1-11e7-a8f1-a41f72fdda5d"
        },
        {
        "Descricao": "teste 3",
        "Id": "4b807449-39a1-11e7-a8f1-a41f72fdda5d"
        }
   ]

缺少什么以使 JSON 中的返回可反序列化以用于 Setor 类?

【问题讨论】:

  • 有什么问题?
  • @echonax 答案是对象数组。我需要返回一个 Setor 数组
  • 你的意思是你的console.log(t); 没有给你想要的吗?
  • @echonax T 是对象数组,应该是扇区数组。这就是强类型返回的确切问题。
  • 为什么不直接使用接口,或者使用类有什么特殊原因?如果是这样,您必须首先修改该类并在其中添加一个构造函数。

标签: arrays json angular typescript rxjs


【解决方案1】:

如果你想使用 Classes ...首先你需要在这种情况下为你的类添加一个构造函数,以便我们可以映射到 Setor 类型的新对象。

export class Setor {
  constructor(
    public descricao: string;
    public id: UUID;
  ) {}
}

然后我们必须从您的响应中映射每个Setor,因为属性不匹配,否则我们可以使用Object.assign 而无需明确说明属性。

obterSetores(): Observable<Setor[]> {
  return this.obterTodos<Setor>()
    .map(res => res.map(x => new Setor(x.Descricao, x.Id)))
}

应该差不多了:)

DEMO

【讨论】:

  • 完美运行!!!!!!但是属性是空的,只需要更正这个就一切正常了!
  • 太好了,很高兴听到!如果属性是空的,可能还有属性不同的问题吗?由于 plunker 使用提供的代码可以正常工作。你只需要仔细检查这些属性,希望你能弄清楚。如果没有,请在您重新创建问题的地方分叉,然后大声喊叫,我可以看看:)
猜你喜欢
  • 2016-08-26
  • 1970-01-01
  • 2019-07-19
  • 2021-12-03
  • 2022-06-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 2018-12-04
相关资源
最近更新 更多