尝试过滤* ngFor指令中的数据

时间:2018-11-02 21:26:06

标签: angular

我正在尝试使用w-ng5包过滤来自Angular的表上的数组数据,但是它正在搜索并且没有找到任何内容(空白列表)。这是我遵循的步骤:

软件包npm

在这里您可以找到w-ng5的Angular文档。

步骤

使用npm

安装软件包
npm install w-ng5 --save

导入我的应用模块

//Pipes of the aplication
import { TruncatePipe } from './pipes/truncate.pipe';
import { PipesModule } from 'w-ng5';

声明app.module部分

imports: [
    BrowserModule,
    RouterModule.forRoot(routes),
    FormsModule,
    NgbModule.forRoot(),
    HttpClientModule,
    ColorPickerModule,
    PdfViewerModule,
    CurrencyMaskModule,
    ReactiveFormsModule,
    NgxPaginationModule,
    NgxTypeaheadModule,
    PipesModule
  ],

执行:

<input type="text" [(ngModel)]="filterInvoice" name="filterInvoice">
<table class="table table-hover table-sm">
  <caption>Tabla de Facturas</caption>
  <thead class="thead-dark">
    <tr>
      <th class="text-center">#</th>
      <th class="text-center">Invoice</th>
      <th class="text-center">Note</th>
      <th class="text-center">State</th>
      <th class="text-center">Customer</th>
      <th class="text-center">Date</th>
      <th class="text-center">Days</th>
      <th class="text-center">Expiration</th>
      <th class="text-center">Payment Type</th>
      <th class="text-center">Option</th>
     </tr>
   </thead>
   <tbody>
     <tr *ngFor="let invoice of invoices | filter : filterInvoice | paginate: { itemsPerPage: 10, currentPage: page }, index as i">
       <td class="text-center">
          {{i+1}}
       </td>
       <td class="text-center">
          {{invoice.number_invoice}}
       </td>
       <td class="text-center">
          {{invoice.note_invoice}}
       </td>
       <td class="text-center">
          {{invoice.state_invoice}}
       </td>
       <td class="text-center">
          {{invoice.customer_invoice}}
       </td>
       <td class="text-center">
          {{invoice.date_invoice}}
       </td>
       <td class="text-center">
          {{invoice.days_invoice}}
       </td>
       <td class="text-center">
          {{invoice.expiration_invoice}}
       </td>
       <td class="text-center">
          {{invoice.payment_invoice}}
       </td>
       <td class="text-center">
          <button type="button" class="btn btn-warning btn-sm">
             Detail
          </button>
       </td>
     </tr>         
   </tbody>        
</table>

数据表JSON

invoices:any[] =[
    {
      number_invoice: '996',
      note_invoice: '0001',
      state_invoice: 'pending',
      customer_invoice: 'Johan Corrales',
      date_invoice: '2018-10-30',
      days_invoice: '30',
      expiration_invoice: '2018-11-30',
      payment_invoice: 'Credit'
    },
    {
      number_invoice: '997',
      note_invoice: 'N/A',
      state_invoice: 'Pay out',
      customer_invoice: 'Richard Castle',
      date_invoice: '2018-10-30',
      days_invoice: '0',
      expiration_invoice: 'N/A',
      payment_invoice: 'Credit'
    },
    {
      number_invoice: '998',
      note_invoice: 'N/A',
      state_invoice: 'pending',
      customer_invoice: 'Kyara Wolff',
      date_invoice: '2018-10-30',
      days_invoice: '30',
      expiration_invoice: '2018-11-30',
      payment_invoice: 'Credit'
    },
    {
      number_invoice: '999',
      note_invoice: 'N/A',
      state_invoice: 'pending',
      customer_invoice: 'Donaldo Trumpete',
      date_invoice: '2018-10-30',
      days_invoice: '30',
      expiration_invoice: '2018-11-30',
      payment_invoice: 'Credit'
    },
    {
      number_invoice: '1000',
      note_invoice: '0001',
      state_invoice: 'pending',
      customer_invoice: 'Mark Wahlber',
      date_invoice: '2018-10-30',
      days_invoice: '30',
      expiration_invoice: '2018-11-30',
      payment_invoice: 'Cash'
    },
    {
      number_invoice: '1001',
      note_invoice: 'N/A',
      state_invoice: 'Pay out',
      customer_invoice: 'Ryan Reynolds',
      date_invoice: '2018-10-30',
      days_invoice: '0',
      expiration_invoice: 'N/A',
      payment_invoice: 'Cash'
    },
  ]

服务发票

  public getInvoice()
  {
    return new Promise(
      resolve=>{
        this.http.get('authentication/consultInvoice')
        .subscribe(
        data => resolve(data)
        )
      }
    )
  };

构造器组件

constructor(private _serviceInvoice:InvoiceService)
  {    
    _serviceInvoice.getInvoice()
    .then(data=>{
      this.invoices = data;
      this.onFilterChange();
    })
    .catch(err=>{
      console.log(err);
    });
  };

这是我从Angular得到的错误> ERROR TypeError: "item is null; can't access its "toString" property"

注释 我知道这一点(来自Angular的文档):

  

过滤,尤其是排序是昂贵的操作。用户   即使是中等大小的列表,体验也会严重恶化   Angular每秒多次调用这些管道方法

3 个答案:

答案 0 :(得分:3)

您可以创建一个过滤器函数,只要您的过滤器字符串发生更改,就会调用该函数。

代码将如下所示:

  isMatch(item) {
    if (item instanceof Object) {
      return Object.keys(item).some((k) => this.isMatch(item[k]));
    } else {
      return item.toString().indexOf(this.filterString) > -1
    }
  }

这将递归遍历对象,并查找任何匹配项。尽管没有必要(请参见对象结构是平坦的),但如果结构发生变化,它可能会很有用。请记住,它是区分大小写的

然后,您需要创建一个调用它的函数,如下所示:

onFilterChange() {
  this.filtered = this.invoices.filter((invoice) => this.isMatch(invoice));
}

并修改输入内容,以便在更改搜索字符串时重新过滤输入内容

<input [(ngModel)]="filterString" (ngModelChange)="onFilterChange()" />

Here is a Stackblitz demo

答案 1 :(得分:1)

您仍然可以使用w-ng5模块在表的每一列上过滤数组数据

只需更改

<tr *ngFor="let invoice of invoices | filter : filterInvoice | 
    paginate: { itemsPerPage: 10, currentPage: page }, index as i">

<tr *ngFor="let invoice of invoices | filter:[
    {field:'number_invoice', value: searchValue}, 
    {field:'note_invoice', value: searchValue}, 
    {field:'state_invoice', value: searchValue}, 
    {field:'customer_invoice', value: searchValue},
    {field:'date_invoice', value: searchValue},
    {field:'days_invoice', value: searchValue},
    {field:'expiration_invoice', value: searchValue}, 
    {field:'payment_invoice', value: searchValue}] | 
    paginate: { itemsPerPage: 10, currentPage: page }, 
 index as i">

这将反复检查对象,并寻找相似之处

答案 2 :(得分:0)

晚安!

因此,请告诉w-ng5您的过滤器不是应用于简单的字符串结构,而是应用于复杂的对象。为此,请在* ngFor的过滤器语法中,使用以下格式:

menu=self.menu1

我实现了您的stackblitz示例,但是,我删除了分页管道:https://stackblitz.com/edit/angular-vlzd3f

请注意,对于复杂对象,您需要告诉过滤器要将过滤器应用于哪些属性 。在我实现的示例中,我对四个字段应用了过滤器:number_invoice,note_invoice,customer_invoice和Payment_invoice

但是,请注意,该组件已升级到已经具有angle 7并具有新功能的版本,现在它已忽略过滤值中的重音符号。新的组件名称也更改为wngx-filter https://www.npmjs.com/package/wngx-filter)。

希望这会有所帮助