Angular 将服务响应映射到要在视图中显示的组件模型

Angular 将服务响应映射到要在视图中显示的组件模型,angular,angular6,Angular,Angular6,我有一个Post API,它返回以下内容: { "data": [ { "id": 1, "title": "Title 1", "content": "Lorem ipsum", "category": { id = 2, name = "A" } "created_at": "2018-10-20 10:14:23" }, { "id": 2, "title": "Title 2"

我有一个Post API,它返回以下内容:

{
  "data": [
    {
      "id": 1,
      "title": "Title 1",
      "content": "Lorem ipsum",
      "category": { id = 2, name = "A" }
      "created_at": "2018-10-20 10:14:23"
    },
    {
      "id": 2,
      "title": "Title 2",
      "content": "Lorem ipsum",
      "category": { id = 4, name = "P" }
      "created_at": "2018-12-20 12:17:41"
    }
  ]
}
我有一个Post List组件,用于显示最上面的帖子,在这里我使用PostService调用API,返回前面的响应:

export class PostListComponent implements OnInit {    

  posts: PostListModel[];

  constructor(private postService: PostService) { }    

  ngOnInit() {

    this.posts = this.postService.getTopPosts()
                     .subscribe(???);
  }    

}
PostListModel如下所示:

export interface PostListModel {
  id: number;
  title: string;
  content: string;
  categoryName: string;
  hidden: boolean;
}
因此,在我的组件上,我需要将API响应映射到PostListModel[],其中所有同名属性都被复制,categoryName和hidden是:

API Category.Name > PostListModel categoryName
PostListModel hidden = false (for all posts)
Hidden是一个属性,允许用户在视图上将行(例如帖子)设置为Hidden。因此,它与API响应无关


注意:请注意,如果这是最好的方法…

您可以在从API收到数据后映射数据

export class PostListComponent implements OnInit {    

  posts: PostListModel[];

  constructor(private postService: PostService) { }    

  ngOnInit() {

    this.posts = this.postService.getTopPosts().map(post=>{id:post.id, title:post.title, content:post.content, categoryName : post.category['name'],  hidden : false}).subscribe(posts=> this.posts);
  }    

}
注意:您可以在服务类本身中执行相同的映射


一旦从API接收到数据,就可以对其进行映射

export class PostListComponent implements OnInit {    

  posts: PostListModel[];

  constructor(private postService: PostService) { }    

  ngOnInit() {

    this.posts = this.postService.getTopPosts().map(post=>{id:post.id, title:post.title, content:post.content, categoryName : post.category['name'],  hidden : false}).subscribe(posts=> this.posts);
  }    

}
注意:您可以在服务类本身中执行相同的映射


对于名称与组件订阅方法中的道具完全匹配的道具,可以使用排列运算符,如:

this.postService.getTopPosts()
.subscribe((s)=>{
  this.posts = s.data.map((item)=>{
    return {
     ...item,
     categoryName:item.category.name
    }
  }
});

对于名称与组件订阅方法中的道具完全匹配的道具,可以使用排列运算符,如:

this.postService.getTopPosts()
.subscribe((s)=>{
  this.posts = s.data.map((item)=>{
    return {
     ...item,
     categoryName:item.category.name
    }
  }
});
我想这样做:

模型:

 export class APIResponseItem {
              id: number
              title: string;
              content: string;
              category: { id: number, name: string }
              created_at: Date
    }


export class PostListModel {
  id: number;
  title: string;
  content: string;
  categoryName: string;
  hidden: boolean;

  constructor(data?: APIResponseItem) {
    if(data) {
      this.id = data.id;
      this.title = data.title;
      this.content = data.content;
      this.categoryName = data.category.name;
      this.hidden = false;
    }
  }
}
服务:

this.postService.getTopPosts().subscribe((response: APIResponseItem[]) => {
      this.posts = [];
      response.forEach(item => {
        this.posts.push(new PostListModel(item))
      });
    });
我想这样做:

模型:

 export class APIResponseItem {
              id: number
              title: string;
              content: string;
              category: { id: number, name: string }
              created_at: Date
    }


export class PostListModel {
  id: number;
  title: string;
  content: string;
  categoryName: string;
  hidden: boolean;

  constructor(data?: APIResponseItem) {
    if(data) {
      this.id = data.id;
      this.title = data.title;
      this.content = data.content;
      this.categoryName = data.category.name;
      this.hidden = false;
    }
  }
}
服务:

this.postService.getTopPosts().subscribe((response: APIResponseItem[]) => {
      this.posts = [];
      response.forEach(item => {
        this.posts.push(new PostListModel(item))
      });
    });

那么订阅是为了什么呢?我没有映射服务中的数据是有原因的。如果服务方法由两个不同的组件调用,比如PostEditComponent和PostListComponent,每个组件的模型稍有不同,您将如何解决它?例如,PostEditModel使用categoryId而不是categoryName,并且没有隐藏属性。欢迎提供任何替代方案的建议。在这种情况下,您可以像我在回答中所做的那样在组件本身中使用
map
。那么订阅什么呢?我没有映射服务中的数据是有原因的。如果服务方法由两个不同的组件调用,比如PostEditComponent和PostListComponent,每个组件的模型稍有不同,您将如何解决它?例如,PostEditModel使用categoryId而不是categoryName,并且没有隐藏属性。欢迎提供任何替代方案的建议。在这种情况下,您可以像我在回答中所做的那样,在组件本身中使用
map
。是的,这就是我在服务器端使用的方法。。。复制到角度,这将是你所拥有的。。。我在服务器端应用程序中使用它,因为它允许应用程序更好地扩展。我只是不确定它在一个有棱角的应用程序上是否算不上什么。我的意思是为每个API服务操作(创建、获取等)和每个组件建立一个模型。如果你的应用程序模块化很好,那么如果你为每个API响应或组件建立了模型,我认为这不是问题。是的,这是我在服务器端使用的方法。。。复制到角度,这将是你所拥有的。。。我在服务器端应用程序中使用它,因为它允许应用程序更好地扩展。我只是不确定它在一个有棱角的应用程序上是否算不上什么。我的意思是为每个API服务动作(创建、获取等)和每个组件建立一个模型。如果你的应用程序模块化很好,那么如果你为每个API响应或组件建立了模型,我认为这不是问题。