Angular - 如何去除 PipeTransform 的抖动?
Angular - How to debounce PipeTransform?
我正在使用 *ngFor
来显示一个 collection,我还有一个 input
将用作过滤条件(这个 input
是一个 formControl
).现在我添加了一个 PipeTransform
来根据 input
过滤我的 collection。
一切都按预期工作,但我不知道如何去抖动。我希望我的 filterPipe
在 input
中最后一次击键后 0.5 秒被调用,但目前它在我的 input
.
中进行任何更改后立即被调用
HTML:
<div class="test-ctr">
<div class="form-ctr">
<form class="example-form" [formGroup]="filterForm">>
<input formControlName="nick" placeholder="ex. hdw">
</form>
</div>
<div class="app-cards-ctr">
<div class="app-card-ctr" *ngFor="let nick of nicks | filterPipe: filterForm.get('nick')?.value">
<app-card [nick]="nick"></app-card>
</div>
</div>
</div>
Component.ts:
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit {
nicks: string[] = ['Siema', 'Elo', 'Tu', 'Hdw3DCtV', 'and', 'Gównow', 'Zdzisiu11', 'Zdzisiu1','Zdzisiu2','Zdzisiu3','Zdzisiu4','Zdzisiu5'];
constructor(private formBuilder: FormBuilder) {}
filterForm = this.formBuilder.group({
nick: ['']
})
ngOnInit(): void {}
}
Pipe.ts:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'filterPipe', pure: true })
export class FilterPipe implements PipeTransform {
transform(value: string[], arg: string): string[] {
console.log(arg);
return value.filter(
(e) => e.toLowerCase().indexOf(arg.toLowerCase()) !== -1
);
}
}
HTML:
<h3>Filter:</h3>
<form [formGroup]="filterForm">
<input type="text" formControlName="nick" />
</form>
<h3>Nicks:</h3>
<div *ngFor="let nick of nicks | filterPipe: (debouncedControl$ | async)">
{{ nick }}
</div>
组件:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
nicks: string[] = [
'Siema',
'Elo',
'Tu',
'Hdw3DCtV',
'and',
'Gównow',
'Zdzisiu11',
'Zdzisiu1',
'Zdzisiu2',
'Zdzisiu3',
'Zdzisiu4',
'Zdzisiu5',
];
constructor(private formBuilder: FormBuilder) {}
filterForm = this.formBuilder.group({
nick: [''],
});
debouncedControl$ = this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500)
);
}
管道:
@Pipe({
name: 'filterPipe',
})
export class FilterPipe implements PipeTransform {
transform(values: string[], inputValue: string): string[] {
return values.filter((v) => {
return (
v.toLowerCase().indexOf((inputValue || '').toLocaleLowerCase()) > -1
);
});
}
}
综上所述,我可能不会伸手去拿 angular 管道。
备用组件解决方案:
@Component({
selector: 'alternate',
template: `
<form [formGroup]="filterForm">
<input type="text" formControlName="nick" />
</form>
<ul>
<li *ngFor="let nick of filteredNicks$ | async"> {{nick}} </li>
</ul>
`,
})
export class AlternateSolutionComponent {
constructor(private formBuilder: FormBuilder) {}
nicks = ['Siema', 'Elo', 'Tu'];
lowercaseIncludes(a: string, b: string): boolean {
return a.toLocaleLowerCase().indexOf(b.toLocaleLowerCase()) > -1;
}
filterForm = this.formBuilder.group({ nick: [''] });
filteredNicks$ = this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500),
map((inputValue) => {
return this.nicks.filter((nick) =>
this.lowercaseIncludes(nick, inputValue)
);
})
);
}
对我来说,最好的方法是在组件内部而不是在模板中使用管道。
constructor(
private filterPipe: FilterPipe
) {}
ngOnInit() {
this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500),
map(value => {
this.nicks.forEach(nick => {
nick = this.filterPipe.transform(value, nick); // or what you want to do
});
})
);
}
我正在使用 *ngFor
来显示一个 collection,我还有一个 input
将用作过滤条件(这个 input
是一个 formControl
).现在我添加了一个 PipeTransform
来根据 input
过滤我的 collection。
一切都按预期工作,但我不知道如何去抖动。我希望我的 filterPipe
在 input
中最后一次击键后 0.5 秒被调用,但目前它在我的 input
.
HTML:
<div class="test-ctr">
<div class="form-ctr">
<form class="example-form" [formGroup]="filterForm">>
<input formControlName="nick" placeholder="ex. hdw">
</form>
</div>
<div class="app-cards-ctr">
<div class="app-card-ctr" *ngFor="let nick of nicks | filterPipe: filterForm.get('nick')?.value">
<app-card [nick]="nick"></app-card>
</div>
</div>
</div>
Component.ts:
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit {
nicks: string[] = ['Siema', 'Elo', 'Tu', 'Hdw3DCtV', 'and', 'Gównow', 'Zdzisiu11', 'Zdzisiu1','Zdzisiu2','Zdzisiu3','Zdzisiu4','Zdzisiu5'];
constructor(private formBuilder: FormBuilder) {}
filterForm = this.formBuilder.group({
nick: ['']
})
ngOnInit(): void {}
}
Pipe.ts:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'filterPipe', pure: true })
export class FilterPipe implements PipeTransform {
transform(value: string[], arg: string): string[] {
console.log(arg);
return value.filter(
(e) => e.toLowerCase().indexOf(arg.toLowerCase()) !== -1
);
}
}
HTML:
<h3>Filter:</h3>
<form [formGroup]="filterForm">
<input type="text" formControlName="nick" />
</form>
<h3>Nicks:</h3>
<div *ngFor="let nick of nicks | filterPipe: (debouncedControl$ | async)">
{{ nick }}
</div>
组件:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
nicks: string[] = [
'Siema',
'Elo',
'Tu',
'Hdw3DCtV',
'and',
'Gównow',
'Zdzisiu11',
'Zdzisiu1',
'Zdzisiu2',
'Zdzisiu3',
'Zdzisiu4',
'Zdzisiu5',
];
constructor(private formBuilder: FormBuilder) {}
filterForm = this.formBuilder.group({
nick: [''],
});
debouncedControl$ = this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500)
);
}
管道:
@Pipe({
name: 'filterPipe',
})
export class FilterPipe implements PipeTransform {
transform(values: string[], inputValue: string): string[] {
return values.filter((v) => {
return (
v.toLowerCase().indexOf((inputValue || '').toLocaleLowerCase()) > -1
);
});
}
}
综上所述,我可能不会伸手去拿 angular 管道。
备用组件解决方案:
@Component({
selector: 'alternate',
template: `
<form [formGroup]="filterForm">
<input type="text" formControlName="nick" />
</form>
<ul>
<li *ngFor="let nick of filteredNicks$ | async"> {{nick}} </li>
</ul>
`,
})
export class AlternateSolutionComponent {
constructor(private formBuilder: FormBuilder) {}
nicks = ['Siema', 'Elo', 'Tu'];
lowercaseIncludes(a: string, b: string): boolean {
return a.toLocaleLowerCase().indexOf(b.toLocaleLowerCase()) > -1;
}
filterForm = this.formBuilder.group({ nick: [''] });
filteredNicks$ = this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500),
map((inputValue) => {
return this.nicks.filter((nick) =>
this.lowercaseIncludes(nick, inputValue)
);
})
);
}
对我来说,最好的方法是在组件内部而不是在模板中使用管道。
constructor(
private filterPipe: FilterPipe
) {}
ngOnInit() {
this.filterForm.controls.nick.valueChanges.pipe(
startWith(''),
debounceTime(500),
map(value => {
this.nicks.forEach(nick => {
nick = this.filterPipe.transform(value, nick); // or what you want to do
});
})
);
}