Angular 2 observable 没有“映射”到模型

Posted

技术标签:

【中文标题】Angular 2 observable 没有“映射”到模型【英文标题】:Angular 2 observable doesn't 'map' to model 【发布时间】:2016-07-09 02:57:04 【问题描述】:

在学习 Angular 2 时,我使用 observable 通过 API 获取一些数据。像这样:

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

我的帖子模型看起来是这样的:

export class Post 

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

我面临的问题是地图操作员没有对 Post 模型做任何事情。例如,我尝试为 img 值设置默认值,但在视图中 post.img 什么也不显示。我什至用另一个模型(Message[])更改了 Post[],并且行为没有改变。任何人都可以解释这种行为吗?

【问题讨论】:

对我来说没有意义的是为什么 Typescript 在强制转换失败或然后将泛型对象传递给需要 Post 类型的函数时不会抛出错误? Typescript 类型检查不起作用吗?泛型对象可以具有不与类型化参数对齐的随机属性,因此不会发生隐式转换,但泛型对象可以毫无问题地传递。 【参考方案1】:

当我想在模板中使用计算属性时,我遇到了类似的问题。

我在这篇文章中找到了一个很好的解决方案:

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

您在模型上创建一个静态方法,该方法接受一个对象数组,然后从映射函数调用该方法。在静态方法中,您可以调用您已经定义的构造函数或使用复制构造函数:

映射方法

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

现有构造函数

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']));
  

复制构造函数

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

如果您使用支持代码完成的编辑器,您可以将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);
  

【讨论】:

谢谢,看起来不错的解决方案!我会再等几天,也许还有其他答案,否则我会将你的答案标记为已接受! 很好的解决方法。不幸的是,如果你想打开它,需要在 tsconfig 中关闭“noImplicitAny”设置。【参考方案2】:

您可以使用 as 关键字将 JSON 反序列化为您的对象。

Angular2 文档有 a tutorial 指导您完成此操作。不过总之...

型号:

export class Hero 
  id: number;
  name: string;

服务:

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

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

组件:

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

【讨论】:

如果我们为类和 json 数据使用不同的参数名称,它是否有效?即如果类有name,我们从json得到user_name 好吧,我不得不说它根本没有回答这个问题。基本上,as syntax(您建议)的工作方式完全&lt;...&gt; 相同。 语法唯一的区别在于&lt;...&gt; 语法 与(.tsx 文件 - JSX 语法)冲突,如this question 中所述.此外,&lt;...&gt;as 在这种情况下都不起作用。以上答案是正确的。

以上是关于Angular 2 observable 没有“映射”到模型的主要内容,如果未能解决你的问题,请参考以下文章

Angular js 2 'node_modules/rxjs/Observable"' 没有导出的成员 'Observable'。导入 Observable

Angular 2 变化检测与 observables

Angular 2 Firebase Observable 承诺不会返回任何东西

为啥订阅在 Angular 中没有 Observable 的情况下工作

在 Angular 中使用 Observer 作为 Observable

如何在 Angular 中管道/映射 Observable