如何处理可观察对象的可选参数?
How to deal with an optional argument to an observable?
我有一个 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);
}
}
我在这里不是 100%,但我相信因为您没有明确订阅过滤器,所以您无法有效地观察它的变化。我会添加
this.filters$.subscribe( res => {
res.pipe(
switchMap(filter => this.service.getItems(filter)
)
})
这应该监听过滤器的创建然后触发 this.service.getItems(filter)
祝你好运!
问题是因为您使用的是 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
不起作用,因为我也在 constructor
中尝试了 this.filter$.next(null)
。
我有一个 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);
}
}
我在这里不是 100%,但我相信因为您没有明确订阅过滤器,所以您无法有效地观察它的变化。我会添加
this.filters$.subscribe( res => {
res.pipe(
switchMap(filter => this.service.getItems(filter)
)
})
这应该监听过滤器的创建然后触发 this.service.getItems(filter)
祝你好运!
问题是因为您使用的是 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
不起作用,因为我也在 constructor
中尝试了 this.filter$.next(null)
。