我有两个组成部分。一个由多选下拉列表组成。另一个显示通过服务从api获取的数据。
我想根据多重选择中选择的值来过滤显示的数据。该如何处理?
stackblitz 在这次堆叠闪电战中,我复制了该结构。 select组件包含multiselect,hello组件显示通过api.service从api获取的数据。在multiselect中选择的值通过另一个过滤器(即filter.service)发送到hello组件。我可以显示所选的值,但我想根据这些值过滤数据。
P.S:在堆栈闪电战中,我明确提到了app.component中两个组件的选择器。但是在我的项目中,组件是通过路由器插座提供的。
答案 0 :(得分:1)
Angular IO Guides(进入基本链接)是解决此类问题的基本知识的好地方。 This section解释了一些组件交互。
在您的情况下,您的两个组件可能是调用您的服务的组件的子组件。该包装器可能会向显示组件提供从API结果复制的列表(或流),并且可能正在侦听下拉组件的输出。当输出触发时,包装器可以修改发送到显示组件的复制列表(或流)。
这是一个粗糙的示例,但作为免责声明,这是理论上的,我没有运行它。
// wrapper html
<multiselect-component (selectionChange)="selectedItems($event)"></multiselect-component>
<display-component [items]="displayItems$ | async"></display-component>
//wrapper ts
private selectedSubject = new BehaviorSubject<any>(); // add your type
set selectedItems(items: any[]) { // add your type
this.selectedSubject.next(items);
}
displayItems$: Observable<any>; // add your own type
ngOnInit() {
// the static 'merge' from 'rxjs' to allow both streams to trigger
this.displayItems$ = merge(
this.apiService.getData(), // should return an observable
this.selectedSubject.asObservable(),
).pipe(
// something similar to this
switchMap((data, filterItems) =>
data.filter(d =>
!filterItems.includes(d)
)
),
);
}
我还将提供免责声明Angular是一个非常自以为是的框架。做事有很多方法!另外,RXJS可以为您做很多事情。这时最简单的方法是做与以前几乎相同的事情。
添加StackBlitz之后:
在this.changeDetectorRef.detectChanges();
内不需要 init
。我也认为您根本不必自己检测更改。我发现,如果必须这样做,通常 (但并非总是如此)意味着计划/结构中有些许问题。还有多种解决方法,我个人坚持使用容器(页面)组件和显示组件。
类似
//display component
ngOnInit() {
// the static 'merge' from 'rxjs' to allow both streams to trigger
this.obs = merge(
this.cardsInfo.getCardsInfo(), // should return an observable
this.filterService.getCategories(),
).pipe(
// something similar to this
switchMap((data, filterItems) =>
data.filter(d =>
!filterItems.includes(d)
)
),
);
}
在我看来,您似乎也正在尝试遵循this StackBlitz中的this Angular Material example (go to table with filtering)。