如何处理可观察的可选参数?

时间:2018-06-12 18:43:44

标签: angular angular2-observables

我有一个Angular组件,它使用service.getItems从服务中获取数据。有时,服务调用很简单,在其他情况下,需要过滤器。可以通过组件属性filter设置此过滤器。

我确信我从根本上遗漏了一些东西,但我无法让它正常工作。我可以让它接受过滤器,或忽略过滤器,但不对过滤器的存在做出反应。

修改下面的代码以实际工作的任何建议?

@Component({}
  selector: 'my-component',
  template: `
    <!-- Items are shown async -->
    {{ items | async }}
  `
})
export class MyComponent {

  //////////////////////////////////////////////////////////////////
  // Initialize the filter observable with a null value
  //////////////////////////////////////////////////////////////////
  constructor(private service) {
    this.filter = null;
  }

  //////////////////////////////////////////////////////////////////
  // Filter observable to hookup the filter value to the service
  //////////////////////////////////////////////////////////////////
  filter$: Subject<Filter> = new Subject<Filter>();

  //////////////////////////////////////////////////////////////////
  // Service call to fetch items
  //////////////////////////////////////////////////////////////////
  items$: Observable<any[]> = this.filters$.pipe(
    switchMap(filter => this.service.getItems(filter));
  );

  //////////////////////////////////////////////////////////////////
  // Allow filter with
  // <my-component [filter]="myFilter">
  //////////////////////////////////////////////////////////////////
  @Input()
  set filter(filter: Filter) {
    this.filter$.next(filter);
  }
}

2 个答案:

答案 0 :(得分:2)

问题是因为您使用的是Subject而不是BehaviorSubject。如果您希望filter$在初始化时发出空值,则需要使用BehaviorSubject。从您items$分配Observable时起,this.filter$没有发出任何内容,因此整个Observable还没有运行。

@Component({
  selector: 'my-component',
  template: `
       <!-- Items are shown async -->
       {{ items$ | async }}
  `
})
export class MyComponent {

 //////////////////////////////////////////////////////////////////
 // Initialize the filter observable with a null value
 //////////////////////////////////////////////////////////////////
 constructor(private service) {
 }

 //////////////////////////////////////////////////////////////////
 // Filter observable to hookup the filter value to the service
 //////////////////////////////////////////////////////////////////
 filter$: BehaviorSubject<Filter> = new BehaviorSubject<Filter>(null);

 //////////////////////////////////////////////////////////////////
 // Service call to fetch items
 //////////////////////////////////////////////////////////////////
 items$: Observable<any[]> = this.filters$.pipe(
   switchMap(filter => this.service.getItems(filter));
 );

 //////////////////////////////////////////////////////////////////
 // Allow filter with
 // <my-component [filter]="myFilter">
 //////////////////////////////////////////////////////////////////
 @Input()
 set filter(filter: Filter) {
   this.filter$.next(filter);
 }
}

这是您可以玩的stackblitz:https://stackblitz.com/edit/angular-ce8jrw

编辑:我无法解释为什么Subject无法正常工作,因为我在this.filter$.next(null)中尝试constructor

答案 1 :(得分:0)

我不是100%在这里,但我相信,因为您没有明确订阅过滤器,所以无法有效地观察它。我会添加

this.service.getItems(filter)

这应该听取过滤器的创建,然后触发/var/lib/boinc-client/global_prefs.xml

祝你好运!