Angular 9个异步管道的过滤结果
Angular 9 filter results of async pipe
我是 angular 的新人,我正在做一个应用程序以更好地学习。我对 HTTP 调用的绑定和过滤结果有疑问。在下面的代码中,我尝试绑定一些数据列表。
在服务中我有一个这样的电话
getTestFields(): Observable<Engagement[]> {
return this.httpClient.get<Engagement[]>(this.url + '/testFields');
}
它基本上是 returns 一些测试字段的列表;在 component.ts 我将调用结果绑定到一个可观察变量。
dataSet$: Observable<Engagement[]>;
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields();
}
在 html 模板中,我绑定如下数据:
<table class="table table-hover" *ngIf="dataSet$ | async as resultSet; else loading">
<tr *ngFor="let item of resultSet" >
<td>{{item.testName}}</td>
<td>{{item.planned}}</td>
<td>{{item.workingOn}}</td>
<td>{{item.reviewed}}</td>
</tr> </table>
直到这里我都没有问题;我成功获取数据并显示在table中。问题是过滤;我不知道如何过滤已经从服务器获得的数据。我不想调用服务器来过滤数据,我想过滤我已经得到的当前列表。
我试过类似下面的方法,但没有用。
filter() {
this.dataSet$ = this.dataSet$.pipe(
switchMap(data => {
return data.filter(p => p.planned)
})
);
}
如何在不向服务器发送新调用的情况下过滤现有的可观察列表?
尝试将 rxjs map
运算符与数组 filter
.
结合使用
Map 转换 observable,因此在本例中我们使用它来转换数组以仅包含 planned
为 true 的项。
import { map } from 'rxjs/operators';
.....
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
map(data => data.filter(p => p.planned)),
);
}
您还可以使用 rxjs
的 filter
运算符 filter
从 Observable 发射数据,但我认为在这种情况下您不需要它。
================ RxJS过滤器的使用===================
import { filter } from 'rxjs/operators';
...
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
// make sure data is truthy and has a length before emitting to
// the consumer (in this case it is the HTML).
filter(data => !!data && !!data.length),
);
}
我同意 AliF50,只需稍作调整,因为我假设您有一个过滤器按钮,或者您想以某种方式在加载数据后过滤掉。
dataSet$: Observable<Engagement[]>;
ngOnInit(): void {
filter();
}
filter() {
this.dataSet$ = this.service.getTestFields().pipe(
map(data => data.filter(p => p.planned)),
);
);
}
还有一种情况是您在加载数据后永远不想去服务器,那么您可能需要在组件级别订阅。
喜欢
dataSet: Engagement[];
ngOnInit(): void {
this.dataSet = this.service.getTestFields().subscribe(response => this.dataSet =
response);
}
filter() {
this.dataSet = this.dataSet.filter(data => data.planned === true)
}
我遇到了一个混合解决方案;职责分离是解决问题的关键;我在一个 async
管道中实现了一个自动完成到它自己的列表,但是我无法正确处理过滤器,所以我们开始:
亲爱的-autocomplete.component.ts
import {
ChangeDetectionStrategy,
Component,
OnInit,
Input,
Output, EventEmitter
} from '@angular/core';
import { FormControl } from '@angular/forms';
import { MyInterface } from '~interfaces-whatsoever';
import { map, startWith } from 'rxjs/operators';
import { Observable } from 'rxjs';
@Component({...})
export class MyDearAutocompleteComponent
implements OnInit
{
@Input() controlName: string;
@Input() control: FormControl;
@Input() options: MyInterface[];
@Output() selectOptionEvent = new EventEmitter<MyInterface>();
filteredOptions: Observable<MyInterface[]>;
ngOnInit() {
this.filteredOptions = this.control.valueChanges.pipe(startWith(''), map(name => this.isOptionNameMatch(name)));
}
isOptionNameMatch(value: string): MyInterface[] {
const clause = (option: MyInterface) => { do your stuff test here };
return (typeof value === 'string') ? this.options.filter(clause) : this.options;
}
selectOption(value: MyInterface) {
this.selectOptionEvent.emit(value);
}
}
其中 @Input() options: MyInterface[];
是您的完整列表,由组件家长使用类似以下内容提供:
options$ | async as options; else loading
...
<app-my-dear-autocomplete ... [options]="options" ... ></app-my-dear-autocomplete>
亲爱的-autocomplete.component.html
<mat-form-field appearance="fill" fxFlex="100">
<mat-label>My dear option list</mat-label>
<input type="text" required matInput [matAutocomplete]="optionAutocomplete" [formControl]="control"/>
<mat-autocomplete #optionAutocomplete="matAutocomplete" (optionSelected)="selectOption($event.option.value)">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.whatsoever }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
这样做并像订阅它的组件一样使用自动完成输出帮助我处理选择事件以及其他组件。
希望对您有所帮助,我当然愿意接受建议
我是 angular 的新人,我正在做一个应用程序以更好地学习。我对 HTTP 调用的绑定和过滤结果有疑问。在下面的代码中,我尝试绑定一些数据列表。
在服务中我有一个这样的电话
getTestFields(): Observable<Engagement[]> {
return this.httpClient.get<Engagement[]>(this.url + '/testFields');
}
它基本上是 returns 一些测试字段的列表;在 component.ts 我将调用结果绑定到一个可观察变量。
dataSet$: Observable<Engagement[]>;
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields();
}
在 html 模板中,我绑定如下数据:
<table class="table table-hover" *ngIf="dataSet$ | async as resultSet; else loading">
<tr *ngFor="let item of resultSet" >
<td>{{item.testName}}</td>
<td>{{item.planned}}</td>
<td>{{item.workingOn}}</td>
<td>{{item.reviewed}}</td>
</tr> </table>
直到这里我都没有问题;我成功获取数据并显示在table中。问题是过滤;我不知道如何过滤已经从服务器获得的数据。我不想调用服务器来过滤数据,我想过滤我已经得到的当前列表。
我试过类似下面的方法,但没有用。
filter() {
this.dataSet$ = this.dataSet$.pipe(
switchMap(data => {
return data.filter(p => p.planned)
})
);
}
如何在不向服务器发送新调用的情况下过滤现有的可观察列表?
尝试将 rxjs map
运算符与数组 filter
.
Map 转换 observable,因此在本例中我们使用它来转换数组以仅包含 planned
为 true 的项。
import { map } from 'rxjs/operators';
.....
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
map(data => data.filter(p => p.planned)),
);
}
您还可以使用 rxjs
的 filter
运算符 filter
从 Observable 发射数据,但我认为在这种情况下您不需要它。
================ RxJS过滤器的使用===================
import { filter } from 'rxjs/operators';
...
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
// make sure data is truthy and has a length before emitting to
// the consumer (in this case it is the HTML).
filter(data => !!data && !!data.length),
);
}
我同意 AliF50,只需稍作调整,因为我假设您有一个过滤器按钮,或者您想以某种方式在加载数据后过滤掉。
dataSet$: Observable<Engagement[]>;
ngOnInit(): void {
filter();
}
filter() {
this.dataSet$ = this.service.getTestFields().pipe(
map(data => data.filter(p => p.planned)),
);
);
}
还有一种情况是您在加载数据后永远不想去服务器,那么您可能需要在组件级别订阅。
喜欢
dataSet: Engagement[];
ngOnInit(): void {
this.dataSet = this.service.getTestFields().subscribe(response => this.dataSet =
response);
}
filter() {
this.dataSet = this.dataSet.filter(data => data.planned === true)
}
我遇到了一个混合解决方案;职责分离是解决问题的关键;我在一个 async
管道中实现了一个自动完成到它自己的列表,但是我无法正确处理过滤器,所以我们开始:
亲爱的-autocomplete.component.ts
import {
ChangeDetectionStrategy,
Component,
OnInit,
Input,
Output, EventEmitter
} from '@angular/core';
import { FormControl } from '@angular/forms';
import { MyInterface } from '~interfaces-whatsoever';
import { map, startWith } from 'rxjs/operators';
import { Observable } from 'rxjs';
@Component({...})
export class MyDearAutocompleteComponent
implements OnInit
{
@Input() controlName: string;
@Input() control: FormControl;
@Input() options: MyInterface[];
@Output() selectOptionEvent = new EventEmitter<MyInterface>();
filteredOptions: Observable<MyInterface[]>;
ngOnInit() {
this.filteredOptions = this.control.valueChanges.pipe(startWith(''), map(name => this.isOptionNameMatch(name)));
}
isOptionNameMatch(value: string): MyInterface[] {
const clause = (option: MyInterface) => { do your stuff test here };
return (typeof value === 'string') ? this.options.filter(clause) : this.options;
}
selectOption(value: MyInterface) {
this.selectOptionEvent.emit(value);
}
}
其中 @Input() options: MyInterface[];
是您的完整列表,由组件家长使用类似以下内容提供:
options$ | async as options; else loading
...
<app-my-dear-autocomplete ... [options]="options" ... ></app-my-dear-autocomplete>
亲爱的-autocomplete.component.html
<mat-form-field appearance="fill" fxFlex="100">
<mat-label>My dear option list</mat-label>
<input type="text" required matInput [matAutocomplete]="optionAutocomplete" [formControl]="control"/>
<mat-autocomplete #optionAutocomplete="matAutocomplete" (optionSelected)="selectOption($event.option.value)">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.whatsoever }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
这样做并像订阅它的组件一样使用自动完成输出帮助我处理选择事件以及其他组件。
希望对您有所帮助,我当然愿意接受建议