【问题标题】:Angular filter table using custom pipe upon button click单击按钮时使用自定义管道的角度过滤器表
【发布时间】:2017-05-14 03:48:06
【问题描述】:

我有一个使用自定义管道成功过滤的表。过滤器基于两个输入,它们共同构成一个表单。我要添加的功能是在单击提交按钮之前不会发生过滤。所以它更像是一个搜索按钮。我找到了大量有关管道的信息,但没有关于在单击按钮时激活它们的信息。

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
  }
}

搜索管道.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;
    });
  }
}

【问题讨论】:

  • 使用 mainpage.component.html 更新您的帖子
  • @Aravind 我试图包含最少的代码,足以让问题被理解。 mainpage.component.html 的哪些部分让您感到困惑?或者您认为缺少什么?
  • 因为您的问题都是关于 按钮单击 和自定义管道。触发点击事件的按钮在哪里?
  • @Aravind 在我的button 标签中显示(click)="submit(secondForm.value)"。我通过添加 submit 函数来编辑我的问题,但它没有任何内容,因为这是我的问题所要问的。

标签: html angular typescript angular2-pipe


【解决方案1】:

您可以使用单击提交时切换的布尔值来切换过滤后的 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”的“数据”。但是,这将覆盖您原来的 theData 数组。所以我会创建一个临时数组,以便您可以恢复为未过滤的 theData。

【讨论】:

  • 您的第一个解决方案更多的是解决问题,而不是我不想尝试但很感激的解决方案。您切换布尔值的解决方案虽然有效!另外,我将如何过滤数据而不是使用管道?我像 @DeborahK 的解决方案一样尝试过,但没有奏效,正如您在 cmets 中看到的那样。
  • 是的,我知道。我只是喜欢 ngIf 的力量。我在回复中添加了过滤解决方案。这与黛博拉几乎相同。我还认为将此功能保留在管道中会更好。因此,您可以轻松地在项目中的其他地方重用。
【解决方案2】:

您可以考虑放弃管道,而是在用户单击按钮时自己过滤数据。

首先,定义表示过滤结果的第二个属性

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);

【讨论】:

  • 当我点击触发submit函数的提交按钮时,这给了我控制台错误value.filter is not a function
  • 我认为这是因为value 是我的表单的值,它来自两个输入。我需要过滤表格,而不是表格
猜你喜欢
  • 2020-07-01
  • 2018-07-22
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
相关资源
最近更新 更多