Primeng table 过滤器不适用于具有嵌套对象的列

Primeng table filter not working on column with nested object

我有一个 primeng table,其中列值是从嵌套 object.I 获得的,我无法使用该列 value.The 过滤器过滤 table 如果工作正常提前输入其他 columns.Please help.Thanks 中的值。

这是我的打字稿:

this.cols = [
      { field: 'name', header: 'Name' },
      { field: 'email', header: 'Email' },
      { field: 'phnNumber', header: 'Contact No' },
      { field: 'grades[0].grade1', header: 'Grade' },

    ];

这是我的过滤器:

   <div class="col-md-6">
    <p-table [columns]="cols" #dt [value]="students" [autoLayout]="true" [paginator]="true" [rows]="10">
        <ng-template pTemplate="caption">
            <div style="text-align: right">
                <i class="fa fa-search" style="margin:4px 4px 0 0"></i>
                <input type="text" pInputText size="30" placeholder="Search" (input)="dt.filterGlobal($event.target.value, 'contains')" class="filter">
            </div>
        </ng-template>
        <ng-template pTemplate="header" let-columns>
            <tr>
                <th class="row-header" *ngFor="let col of columns" [pSortableColumn]="col.field">
                    {{col.header}}
                    <p-sortIcon class="" [field]="col.field" ariaLabel="Activate to sort" ariaLabelDesc="Activate to sort in descending order" ariaLabelAsc="Activate to sort in ascending order">
                    </p-sortIcon>
                </th>

            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-student let-columns="columns">
            <tr class="center-text">
                <td class="row-cell">{{student.name}}</td>
                <td class="row-cell">
                    {{student.email}}
                </td>

                <td class="row-cell">{{student.grades[0].grade1}}</td>

            </tr>
        </ng-template>
    </p-table>

</div>

如果我在成绩列中输入任何值,我得到的响应是空的。 我认为使用 grades[0].grade1 作为字段存在一些问题。

JSON结构:

[
    {
        "name": "Test",
        "email": null,
        "phnNumber": 1,
        "grades": [
            {
                "grade1": "A",
                "grade2": "B"
            }
        ]
    }
]

Stackblitz- https://stackblitz.com/edit/angular-dbwfep

您可以在列配置中使用 name[0].grade as filed 属性。它可以是任何嵌套对象。过滤器正在运行。

事实是 table 上的数据应该相同 属性。

更新: 您必须实现 table 的自定义排序和过滤方法。排序是动态的,因为我们知道用户希望根据点击事件对哪个字段进行排序,识别键很容易。但是在我们不知道的过滤器中,过滤器适用于所有字段,所以我现在已经使用 'grade1' 字段进行过滤,您可以添加尽可能多的字段并在过滤器之后删除。

我想在嵌套对象的情况下,默认情况下它不起作用,因此您必须添加自定义实现。希望这有帮助。

component.html

<hello name="{{ title }}"></hello>
<div class="col-md-6">
    <p-table [columns]="cols" #dt [value]="students" [autoLayout]="true" [paginator]="true" [rows]="10" (onSort)="onSort($event)">
        <ng-template pTemplate="caption">
            <div style="text-align: right">
                <i class="fa fa-search" style="margin:4px 4px 0 0"></i>
                <input type="text" pInputText size="30" placeholder="Search" (input)="myFilter($event)" class="filter">
            </div>
        </ng-template>
        <ng-template pTemplate="header" let-columns>
            <tr>
                <th class="row-header" *ngFor="let col of columns" [pSortableColumn]="col.field">
                    {{col.header}}
                    <p-sortIcon class="" [field]="col.field" ariaLabel="Activate to sort" ariaLabelDesc="Activate to sort in descending order" ariaLabelAsc="Activate to sort in ascending order">
                    </p-sortIcon>
                </th>

            </tr>
        </ng-template>
        <ng-template pTemplate="body" let-student let-columns="columns">
            <tr class="center-text">
                <td class="row-cell">{{student.name}}</td>
                <td class="row-cell">
                    {{student.email}}
                </td>
                <td class="row-cell">
                    {{student.phnNumber}}
                </td>
                <td class="row-cell">{{student.grades[0].grade1}}</td>

            </tr>
        </ng-template>
    </p-table>

</div>

component.ts

import { FormControl, FormGroup } from "@angular/forms";
import { Component,
         ViewChild,
         AfterViewInit,
         ElementRef } from '@angular/core';
@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  title = "Filter in Table";
  cols = [];
  grades = [{ grade1: "grade1", grade2: "grade2" }];
  students = [];
  @ViewChild('dt',{read: '',static:true}) dt: any;

  constructor() {
    this.cols = [
      { field: "name", header: "Name" },
      { field: "email", header: "Email" },
      { field: "phnNumber", header: "Contact No" },
      { field: this.grades[0]["grade1"], header: "Grade1" }
    ];
    this.students = [
      {
        name: "Abhinav",
        email: "abhinavkumar985@gmail.com",
        phnNumber: "23456787654",
        grades: [
          {
            grade1: "AA",
            grade2: "X"
          }
        ]
      },
      {
        name: "Ravi",
        email: "Ravi@gmail.com",
        phnNumber: "1234543666",
        grades: [
          {
            grade1: "CC",
            grade2: "Y"
          }
        ]
      },
      {
        name: "Harsh",
        email: "hardss@gmail.com",
        phnNumber: "23212324",
        grades: [
          {
            grade1: "BB",
            grade2: "Z"
          }
        ]
      }
    ];
  }
  myFilter(e){
    this.dt.value.forEach((e)=>{
      e['grade1'] = e['grades'][0]['grade1'];
    });
    this.dt.filterGlobal(e.target.value, 'contains');
    setTimeout(()=>{
      this.dt.value.forEach((e)=>{
      delete e['grade1'];
    });
    },500)
  }
  onSort(e){
    let filed = e.field;
    let arr = [...this.students];
    if(filed === 'grade1'){
      // custome sort only for these fields

      let order = e.order; // 1 means abc and -1 means cba
      if(order === 1){
        this.students.sort( this.OrderListBy(filed) );
      }else{
        this.students.sort( this.OrderListBy(filed) ).reverse();
      }
    }
  }
  OrderListBy(prop) {
    return function (a, b) {
        if (a['grades'][0][prop] > b['grades'][0][prop]) {
            return 1;
        }
        else if (a['grades'][0][prop] < b['grades'][0][prop]) {
            return -1;
        }
        return 0;
    }
  }
}

see updated working example