html - กรองตาราง Angular โดยใช้ pipe ที่กำหนดเองเมื่อคลิกปุ่ม
ฉันมีตารางซึ่งฉันสามารถกรองได้สำเร็จโดยใช้ pipe ที่กำหนดเอง การกรองขึ้นอยู่กับสองอินพุตซึ่งรวมกันเป็นแบบฟอร์ม ฟังก์ชันที่ฉันต้องการเพิ่มคือการที่การกรองจะไม่เกิดขึ้นจนกว่าจะมีการคลิกปุ่มส่ง ดังนั้นมันจึงเหมือนปุ่มค้นหา ฉันพบข้อมูลมากมายเกี่ยวกับ pipes แต่ไม่พบเรื่องการเรียกใช้งานพวกมันเมื่อมีการคลิกปุ่มเลย
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
}
}
search-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;
});
}
}
คำตอบ #1
คุณอาจพิจารณายกเลิกการใช้ pipe และแทนที่จะทำเพียงกรองข้อมูลด้วยตัวเองเมื่อผู้ใช้คลิกปุ่ม
ก่อนอื่น กำหนดคุณสมบัติที่สองซึ่งแทนผลลัพธ์ที่ถูกกรอง
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);
คำตอบ #2
คุณสามารถสลับลูปที่กรองแล้วด้วยค่าบูลีนที่ถูกสลับเมื่อคุณคลิกส่ง:
*.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' ผ่าน pipe ด้วยเช่นกัน ดังนั้น pipe จะไม่ทำการกรองจนกว่า 'filterToggle' จะเป็นจริง ดังนั้นถ้าคุณคลิก submit toggle จะต้องเปลี่ยนเป็น true และ pipe จะทำการกรอง
ดังนั้น *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 เดิมของคุณโดยการกรองมัน คุณอาจต้องลองปรับนิพจน์บูลีนที่กำหนดว่าจะกรองอะไร สิ่งที่ควรรักษาไว้คือเฉพาะ 'data' ที่มีวันที่เริ่มต้นมากกว่าหรือเท่ากับ 'this.startDateValue' ของคุณและน้อยกว่าหรือเท่ากับ 'this.endDateValue' ของคุณ อย่างไรก็ตาม นี่จะทำให้เขียนทับอาร์เรย์ theData เดิมของคุณ ดังนั้นฉันจะแนะนำให้สร้างอาร์เรย์ชั่วคราวเพื่อให้คุณสามารถกลับไปยัง theData เดิมที่ไม่ได้กรอง
