【问题标题】:Angular2. Map http response to concrete object instance角2。将 http 响应映射到具体对象实例
【发布时间】:2017-01-05 09:25:28
【问题描述】:

处理http响应的常用方法是这样的:

return this._http.get(url)
           .map((res: Response) => res.json());

它为您提供Observable<Object[]>,其中Object 是从json 反序列化动态创建的类型。 然后你可以在*ngFor="let item of result | async"等中使用这个结果...

我想获得一个特定的类型实例(意思是使用new 运算符来调用该类型的构造函数)。 尝试了不同的方法来实现类似的目标:

.map((res: Response) => { let obj = res.json(); return new MyObject(obj.id, obj.name);})

但收到此错误:Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

这种方式似乎行得通,但太复杂了,可能效果不佳:

.map((res: Response) => {
    let results = <MyObject[]>[];
    let obj = res.json();
    obj.forEach(
        function (o: any) {
            results.push(new MyObject(o.id, o.name));
        }
    );
    return results;
}

谢谢!

【问题讨论】:

标签: json angular rxjs angular-http


【解决方案1】:

如果您知道要从 JSON 中解构什么类型的对象(您可能会这样做),您可以创建一个从 Object 返回实例的静态方法。

class MyClass {

  prop: number;

  static fromObject(src: Object) {
    var obj = new MyClass();
    obj.prop = src.prop;
    return obj;
  }
}

然后将 JSON 响应转换为 MyClass 的实例:

Rx.Observable.of('[{"prop":1},{"prop":2},{"prop":3}]')
  .map(val => JSON.parse(val))
  .exhaustMap(val => new Rx.Observable.from(val))
  .map(val => MyClass.fromObject(val))
  .subscribe(
    item => console.log('Next: ', item),
    error => console.log('Error:', error),
    _ => console.log('Completed')
  );

这是如何工作的:

  1. .map(val =&gt; JSON.parse(val)) 只是将响应转换为 JSON,它是一个对象数组。

  2. .exhaustMap(val =&gt; new Rx.Observable.from(val)) 将每个值转换为 Observable,exhaustMap 将它们展平,因此 JSON 中的每个对象都将单独发出。

  3. .map(val =&gt; MyClass.fromObject(val)) 再次使用map 将每个Object 转换为MyClass 的实例。

观看现场演示:http://jsfiddle.net/f5k9zdh1/1/

【讨论】:

  • 有趣。我的口味仍然太多代码;)但我会更深入地研究。谢谢。
【解决方案2】:
.map((res: Response) => res.json().map(obj => new MyObject(obj.id, obj.name)))

【讨论】:

  • 纯代码答案没有帮助。请尝试解释您的代码如何解决 OP 的问题。其他通过搜索找到这个问题的人可能没有你那么有经验;帮助他们理解你的答案。
【解决方案3】:

试试这个语法,你把它转换成你的对象:

 this.http.post(this.constants.taskUrl + parm, { headers: headers })
            .map((response: Response) => {
                var res = response.json();
                var result = <DataResponseObject>response.json();
                return result;
            })

【讨论】:

  • 这里的交易是response.json() 给你一个对象数组。我用似乎可行的方式更新了我的问题,但我不喜欢这种方式。
猜你喜欢
  • 2016-06-05
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-10
相关资源
最近更新 更多