简体   繁体   English

在Angular 2中共享和更新可观察数据

[英]Share and update Observable data in Angular 2

I have 2 components - object-list and search-filter in my app. 我的应用程序包含2个组件- object-listsearch-filter Also I have a fetch-service with getObjects(page, filter) method. 我也有一个带getObjects(page, filter)方法的fetch-service I want to implement a scenario where object-list fetches all data via getObjects method and then search-filter will apply some filters to getObjects and object-list should automatically update. 我想实现一个方案,其中object-list通过getObjects方法获取所有数据,然后search-filter将一些过滤器应用于getObjects并且object-list应自动更新。 Here is some code: 这是一些代码:

FetchService FetchService

objects: Observable<any>;    

getObjects(page: number, filter): void {
  let headers = new Headers();
  headers.append('Content-Type', 'application/json');

  const offset = (page - 1)* this.pageSize;
  let url = this.objectsBaseUrl;

  //apply filter
  if (filter) {
    url = `${url}?filter=${JSON.stringify(filter)}`
  }

  this.objects = this.http.get(url)
    .map((response: Response) => {
      return response.json() || {}
    })
    .catch(this.handleError);
}

ObjectListComponent ObjectListComponent

constructor(private fetch: FetchService) {}
ngOnInit(): void {
  this.fetch.getObjects(this.initialPage);
  this.objects = this.fetch.objects; // I need an Observable object to use with async pipe with *ngFor
}

getPage(page: number) {
    this.fetch.getObjects(page); //here this.objects variable probably should be update because this methods replaces this.fetch.objects
}

SearchFilter SearchFilter

constructor(private fetch: FetchService) {}

apply() {
  //some filter calculations
  this.fetch.getObjects(1, this.filter);
}

I don't use subscribe to objects because I put it to async pipe in *ngFor . 我不使用subscribe objects因为我将其放入*ngFor异步管道。 But as far as I'm concerned async pipe uses subscribe inside. 但是就我而言,异步管道使用内部subscribe The problem is that the list updates only once when ngOnInit fires. 问题在于,当ngOnInit触发时,列表仅更新一次。 What's going wrong? 怎么了

The SearchFilter component should NOT be in charge of fetching the data. SearchFilter组件不应负责获取数据。

Here's how I would do it: 这是我的处理方式:

1) Create 3 components 1)创建3个组件

  • A parent component , aka "smart component", to handle all the logic of listening to filter changes and fetching the data with FetchService . 一个父组件 ,也称为“智能组件”,用于处理侦听过滤器更改和使用FetchService提取数据的所有逻辑。 The parent component has two children displayed in its template: 父组件的模板中显示了两个子组件:
  • First child: SearchFilterComponent is a "dumb component" (or presentational component). 第一个孩子: SearchFilterComponent是一个“哑组件”(或表示组件)。 Its only job is to emit an @Output event every time the filters change, passing the latest filter values to its parent. 它唯一的工作是每次过滤器更改时都发出一个@Output事件,将最新的过滤器值传递给其父级。
  • Second child: ObjectListComponent is also a "dumb component". 第二个子对象: ObjectListComponent也是一个“哑组件”。 Its only job is to display the list of objects provided by its parent component via an @Input property. 它的唯一工作是通过@Input属性显示其父组件提供的对象列表。

2) Implement the following workflow 2)实施以下工作流程

  • When filters change in SearchFilterComponent , emit an @Output event passing the latest filter values, eg this.filtersChanged.emit(filters) . 当过滤器在SearchFilterComponent更改时,发出一个@Output事件,传递最新的过滤器值,例如this.filtersChanged.emit(filters)
  • In the parent component, listen to filter changes with <search-filter (filtersChanged)="getObjects($event)"> . 在父组件中,使用<search-filter (filtersChanged)="getObjects($event)">监听过滤器更改。 The getObjects(filters) method will re-fetch the objects on every filter change; getObjects(filters)方法将在每次过滤器更改时重新获取对象; it should store the fetched objects in a property of the parent component, let's call it results . 它应该将获取的对象存储在父组件的属性中,我们称其为results
  • Then, the parent component passes results to its child component ObjectListComponent via an @Input property called objects : <object-list [objects]="results"> . 然后,父组件通过称为objects的@Input属性将results传递给子组件ObjectListComponent<object-list [objects]="results"> The object list should refresh automatically every time the input changes. 每次输入更改时,对象列表应自动刷新。

Hopefully my explanations will make sense. 希望我的解释会有意义。 Read up on @Input and @Output on the angular.io site if you're not familiar with those. 如果您不熟悉@@ Input和@Output,请在angular.io网站上阅读。 I don't have time to create a Plunkr, so please post questions if anythings seems unclear. 我没有时间创建Plunkr,所以如果有什么不清楚的地方,请发表问题。

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

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