简体   繁体   English

Angular 2 observable不会“映射”到模型

[英]Angular 2 observable doesn't 'map' to model

As I'm learning Angular 2 I used an observable to fetch some data via an API. 当我正在学习Angular 2时,我使用了一个observable来通过API获取一些数据。 Like this: 像这样:

getPosts() {
        return this.http.get(this._postsUrl)
            .map(res => <Post[]>res.json())
            .catch(this.handleError);
    }

My post model looks is this: 我的帖子模型看起来是这样的:

export class Post {

constructor(
    public title: string,
    public content: string,
    public img: string = 'test') {
}

The problem I'm facing is that the map operator doesn't do anything with the Post model. 我面临的问题是地图运算符对Post模型没有任何作用。 For example, I tried setting a default value for the img value but in the view post.img displays nothing. 例如,我尝试为img值设置默认值,但在视图post.img中没有显示任何内容。 I even changed Post[] with an other model (Message[]) and the behaviour doesn't change. 我甚至用另一个模型(Message [])更改了Post [],并且行为没有改变。 Can anybody explain this behaviour? 任何人都可以解释这种行为吗?

I had a similar issue when I wanted to use a computed property in a template. 当我想在模板中使用计算属性时,我遇到了类似的问题。

I found a good solution in this article: 我在本文中找到了一个很好的解决方案:

http://chariotsolutions.com/blog/post/angular-2-beta-0-somnambulant-inauguration-lands-small-app-rxjs-typescript/ http://chariotsolutions.com/blog/post/angular-2-beta-0-somnambulant-inauguration-lands-small-app-rxjs-typescript/

You create a static method on your model that takes an array of objects and then call that method from the mapping function. 您在模型上创建一个静态方法,该方法接受一个对象数组,然后从映射函数中调用该方法。 In the static method you can then either call the constructor you've already defined or use a copy constructor: 在静态方法中,您可以调用已经定义的构造函数或使用复制构造函数:

Mapping Method 映射方法

getPosts() {
  return this.http.get(this._postsUrl)
    .map(res => Post.fromJSONArray(res.json()))
    .catch(this.handleError);
}

Existing Constructor 现有的构造函数

export class Post {
  // Existing constructor.
  constructor(public title:string, public content:string, public img:string = 'test') {}

  // New static method.
  static fromJSONArray(array: Array<Object>): Post[] {
    return array.map(obj => new Post(obj['title'], obj['content'], obj['img']));
  }
}

Copy Constructor 复制构造函数

export class Post {
  title:string;
  content:string;
  img:string;

  // Copy constructor.
  constructor(obj: Object) {
    this.title = obj['title'];
    this.content = obj['content'];
    this.img = obj['img'] || 'test';
  }

  // New static method.
  static fromJSONArray(array: Array<Object>): Post[] {
    return array.map(obj => new Post(obj);
  }
}

If you're using an editor that supports code completion, you can change the type of the obj and array parameters to Post : 如果您使用的是支持代码完成的编辑器,则可以将objarray参数的类型更改为Post

export class Post {
  title:string;
  content:string;
  img:string;

  // Copy constructor.
  constructor(obj: Post) {
    this.title = obj.title;
    this.content = obj.content;
    this.img = obj.img || 'test';
  }

  // New static method.
  static fromJSONArray(array: Array<Post>): Post[] {
    return array.map(obj => new Post(obj);
  }
}

You can use the as keyword to de-serialize the JSON to your object. 您可以使用as关键字将JSON反序列化到您的对象。

The Angular2 docs have a tutorial that walks you through this. Angular2文档有一个教程 ,可以指导您完成此操作。 However in short... 但总之......

Model: 模型:

export class Hero {
  id: number;
  name: string;
}

Service: 服务:

...
import { Hero } from './hero';

...
get(): Observable<Hero> {
    return this.http
               .get('/myhero.json')
               .map((r: Response) => r.json() as Hero);
}

Component: 零件:

get(id: string) {
    this.myService.get()
      .subscribe(
        hero => {
          console.log(hero);
        },
        error => console.log(error)
      );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM