Angular 过滤器 table 在单击按钮时使用自定义管道
Angular filter table using custom pipe upon button click
我有一个 table,我使用自定义管道成功过滤了它。过滤器基于两个输入,它们一起构成一个表单。我要添加的功能是在单击提交按钮之前不进行过滤。所以它更像是一个搜索按钮。我找到了很多关于管道的信息,但没有关于在单击按钮时激活它们的信息。
mainpage.component.html:
<div>
<label>Start Date:</label>
<input type="text" [(ngModel)]="startDateValue">
</div>
<label>End Date:</label>
<input type="text" [(ngModel)]="endDateValue">
</div>
//'let idx=index' and 'let even=even' are used to change color of the rows but I took out that code. The 'onClick' function just takes the row and uses an EventEmitter to output it.
<tr *ngFor="let dPoint of theData | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
//the button that will execute the filtering
<button type="submit" class="btn icon-search" [disabled]="!secondForm.valid" (click)="submit(secondForm.value)"></button>
mainpage.component.ts:
@Component({
selector: 'main-page',
styleUrls: ['../app.component.css'],
templateUrl: 'mainpage.component.html',
providers: [DataTableService, DatePipe]
})
export class MainPageComponent implements OnInit {
secondForm : FormGroup;
theData:DataTable[] = [];
constructor(fb: FormBuilder, private datePipe: DatePipe, private dataService: DataTableService, private cdRef:ChangeDetectorRef){
this.secondForm = fb.group({
'startDate' : [null, Validators.required],
'endDate' : [null, Validators.required]
}, {validator: this.endDateAfterOrEqualValidator})
}
getTable(): void {
this.dataService.getTable().then(theData => this.theData = theData);
this.cdRef.detectChanges();
}
submit(value: any){
//where I'd want to trigger the filtering/pipe
}
}
搜索-pipe.ts:
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "searchDates"
})
export class SearchPipe implements PipeTransform {
transform(value, minDate , maxDate){
return value.filter(row => {
return row.tStartDate >= minDate && row.tEndDate <= maxDate;
});
}
}
您可以使用单击提交时切换的布尔值来切换已过滤的 for 循环:
*.html:
<div>
<label>Start Date:</label>
<input type="text" [(ngModel)]="startDateValue">
</div>
<label>End Date:</label>
<input type="text" [(ngModel)]="endDateValue">
</div>
<tr *ngIf="filterToggle" *ngFor="let dPoint of theData | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
<tr *ngIf="!filterToggle" *ngFor="let dPoint of theData; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
//the button that will execute the filtering
<button type="submit" class="btn icon-search" [disabled]="!secondForm.valid" (click)="submit()"></button>
</div>
*.ts:
submit() {
this.filterToggle = !this.filterToggle;
}
没有保留模板代码,但它应该可以工作。
另一个想法是也通过管道发送布尔值 'filterToggle',这样管道本身不会过滤,除非 'filterToggle' 为真。因此,如果您单击提交,开关应更改为 true,并且管道将进行过滤。
所以你的 *ngFor 看起来像这样:
<tr *ngFor="let dPoint of theData | searchDates:startDateValue:endDate:filterToggle; let idx = index; let even=even">
...
</tr>
或者,您可以只过滤您的实际数据,而不是将其通过管道。
submit(){
this.theData = this.theData.filter(data =>
return data.tStartDate >= this.startDateValue && data.tEndDate <= this.endDateValue);
}
因此,当您点击提交时,通过过滤更改您原来的 theData 数组。您可能需要使用布尔表达式来确定要过滤的内容。它应该只保留开始日期大于或等于您的 'this.startDateValue' 且小于或等于您的 'this.endDateValue' 的 'data'。但是,这将覆盖您原来的 theData 数组。所以我会创建一个临时数组,这样您就可以恢复到未过滤的 theData。
您可以考虑放弃管道,而是在用户单击按钮时自己过滤数据。
首先,定义第二个 属性 表示过滤后的结果
let theFilteredData: DataTable[]
更改您的绑定以改为绑定到 theFilteredData:
*ngFor="let dPoint of theFilteredData;" //rest of *ngFor not included
在提交函数中:
this.theFilteredData = this.theData.filter(row =>
return row.tStartDate >= minDate && row.tEndDate <= maxDate);
我有一个 table,我使用自定义管道成功过滤了它。过滤器基于两个输入,它们一起构成一个表单。我要添加的功能是在单击提交按钮之前不进行过滤。所以它更像是一个搜索按钮。我找到了很多关于管道的信息,但没有关于在单击按钮时激活它们的信息。
mainpage.component.html:
<div>
<label>Start Date:</label>
<input type="text" [(ngModel)]="startDateValue">
</div>
<label>End Date:</label>
<input type="text" [(ngModel)]="endDateValue">
</div>
//'let idx=index' and 'let even=even' are used to change color of the rows but I took out that code. The 'onClick' function just takes the row and uses an EventEmitter to output it.
<tr *ngFor="let dPoint of theData | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
//the button that will execute the filtering
<button type="submit" class="btn icon-search" [disabled]="!secondForm.valid" (click)="submit(secondForm.value)"></button>
mainpage.component.ts:
@Component({
selector: 'main-page',
styleUrls: ['../app.component.css'],
templateUrl: 'mainpage.component.html',
providers: [DataTableService, DatePipe]
})
export class MainPageComponent implements OnInit {
secondForm : FormGroup;
theData:DataTable[] = [];
constructor(fb: FormBuilder, private datePipe: DatePipe, private dataService: DataTableService, private cdRef:ChangeDetectorRef){
this.secondForm = fb.group({
'startDate' : [null, Validators.required],
'endDate' : [null, Validators.required]
}, {validator: this.endDateAfterOrEqualValidator})
}
getTable(): void {
this.dataService.getTable().then(theData => this.theData = theData);
this.cdRef.detectChanges();
}
submit(value: any){
//where I'd want to trigger the filtering/pipe
}
}
搜索-pipe.ts:
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "searchDates"
})
export class SearchPipe implements PipeTransform {
transform(value, minDate , maxDate){
return value.filter(row => {
return row.tStartDate >= minDate && row.tEndDate <= maxDate;
});
}
}
您可以使用单击提交时切换的布尔值来切换已过滤的 for 循环:
*.html:
<div>
<label>Start Date:</label>
<input type="text" [(ngModel)]="startDateValue">
</div>
<label>End Date:</label>
<input type="text" [(ngModel)]="endDateValue">
</div>
<tr *ngIf="filterToggle" *ngFor="let dPoint of theData | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
<tr *ngIf="!filterToggle" *ngFor="let dPoint of theData; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>
//the button that will execute the filtering
<button type="submit" class="btn icon-search" [disabled]="!secondForm.valid" (click)="submit()"></button>
</div>
*.ts:
submit() {
this.filterToggle = !this.filterToggle;
}
没有保留模板代码,但它应该可以工作。
另一个想法是也通过管道发送布尔值 'filterToggle',这样管道本身不会过滤,除非 'filterToggle' 为真。因此,如果您单击提交,开关应更改为 true,并且管道将进行过滤。
所以你的 *ngFor 看起来像这样:
<tr *ngFor="let dPoint of theData | searchDates:startDateValue:endDate:filterToggle; let idx = index; let even=even">
...
</tr>
或者,您可以只过滤您的实际数据,而不是将其通过管道。
submit(){
this.theData = this.theData.filter(data =>
return data.tStartDate >= this.startDateValue && data.tEndDate <= this.endDateValue);
}
因此,当您点击提交时,通过过滤更改您原来的 theData 数组。您可能需要使用布尔表达式来确定要过滤的内容。它应该只保留开始日期大于或等于您的 'this.startDateValue' 且小于或等于您的 'this.endDateValue' 的 'data'。但是,这将覆盖您原来的 theData 数组。所以我会创建一个临时数组,这样您就可以恢复到未过滤的 theData。
您可以考虑放弃管道,而是在用户单击按钮时自己过滤数据。
首先,定义第二个 属性 表示过滤后的结果
let theFilteredData: DataTable[]
更改您的绑定以改为绑定到 theFilteredData:
*ngFor="let dPoint of theFilteredData;" //rest of *ngFor not included
在提交函数中:
this.theFilteredData = this.theData.filter(row =>
return row.tStartDate >= minDate && row.tEndDate <= maxDate);