Angular:从组件中的service中过滤数据



我有一个类DataService从后端获取数据:

@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}
getEntries() : Observable<Array<DataEntry>> {
return this.http.get<Array<DataEntry>>('http://192.168.0.103:3000/data');
}
getSensors() : Observable<Array<Sensor>> {
return this.http.get<Array<Sensor>>('http://192.168.0.103:3000/sensor');
}
}

和包含各种FilterComponents的FilterCollectionComponent(目前只有一个,但将来会有很多):

@Component({
selector: 'app-filter-collection',
templateUrl: './filter-collection.component.html',
styleUrls: ['./filter-collection.component.css']
})
export class FilterCollectionComponent implements OnInit {
_FilterType = FilterType;
completeData : DataEntry[] = [];
@ViewChild('dateRangeFilter') dateRangeFilter?: ElementRef<FilterComponent>;
constructor(private dataService: DataService) { }
onFilterApply() : void {
}
ngOnInit(): void {
this.dataService.getEntries().subscribe(data => {
this.completeData = data;
});
}
}

与此HTML:

<mat-label>Datefilter:</mat-label>
<div style="display: inline-block; margin-right: 1rem;"></div>
<app-filter #dateRangeFilter [filter]="_FilterType.DateRangeFilter"></app-filter>
<button mat-raised-button color="accent" (click)="onFilterApply()">
Apply
<mat-icon>filter_alt</mat-icon>
</button>

我有两个angular组件,它们需要数据服务中的数据来显示它们。现在,我不希望它们直接订阅原始数据,而是希望它们在过滤原始数据后订阅来自FilterCollectionComponent的事件(用户可以随时过滤数据)。

我对Angular不是很熟悉——你知道什么是最好的实现方式吗?

步骤1。FilterCollectionComponent:将completeData改为Observable Type:

completeData$ : Observable<DataEntry[]> = of([]);

步骤2。FilterCollectionComponent:更改onInit

ngOnInit(): void {
this.completeData$ = this.dataService.getEntries();
}

步骤3。FilterCollectionComponent模板:你的子组件将访问FilterCollectionComponent的completeData$ Observable中的数据,其中订阅/取消订阅将由asynctype处理。

<app-filter [dataEntries]="completeData$ | async" #dateRangeFilter1 [filter]="_FilterType.DateRangeFilter"></app-filter>
<app-filter [dataEntries]="completeData$ | async" #dateRangeFilter2 [filter]="_FilterType.YYFilter"></app-filter>
<app-filter [dataEntries]="completeData$ | async" #dateRangeFilter3 [filter]="_FilterType.XXFilter"></app-filter>

访问<app-filter>中的dataEntries。对于性能,你可以在你的AppFilterComponent中使用changeDetection: ChangeDetectionStrategy.OnPush,,如果他真的是一个表示组件

@Component({
selector: 'app-filter',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
App Filter Works!!
<ul *ngFor="let item of dataEntries">
<li>{{ item.id }} | {{ item.name }} | {{ item.city }}</li>
</ul>
`
})
export class AppFilterComponent {
name = 'Filter';
@Input()
dataEntries: DataEntry[];
}

在你的过滤器方法中,只需将过滤后的数据分配给this.completeData$,并将影响所有子<app-filter>

onFilterApply() : void {
this.completeData$ = //api call
//Or Example filter by john name
this.completeData$ = this.completeData$.pipe(
switchMap(dataEntryList =>
of(dataEntryList.filter(item => item.name === 'John'))
)
);
}

此外,您还可以为每个<app-filter>需要过滤数据,这样您就不需要为每个子[filter]="_FilterType.XXFilter"提供数据。但现在我希望我认为这是足够的根据你的问题。

演示

最新更新