【问题标题】:Display nested object in column in primeng在primeng的列中显示嵌套对象
【发布时间】:2018-01-08 06:54:07
【问题描述】:

我正在按照primeng docs中给出的模板选项在primeng数据表列中创建与列数据并排的链接,但我无法使用{{data[col.field]}}显示嵌套对象。

<p-column [field]="col.field" [header]="col.header" [sortable]="col.sortable" [filter]="col.filter" [editable]="col.editable" [filterPlaceholder]="col.filterPlaceholder" styleClass="{{col.class}}">
                <ng-template let-col let-data="rowData" let-ri="rowIndex" pTemplate="body">
                    <span *ngIf="!col.field.includes('.')" >{{data[col.field]}}</span>
                    <!-- <span *ngIf="col.field.includes('.')">{{data[col.field.split('.')[0]][col.field.split('.')[1]]}}</span> this does not work because field is like x.y-->
                    <!-- I have some other buttons here as well --> 
                </ng-template>
        </p-column>

我怎样才能做到这一点?

共享整个代码 -->

<p-dataTable [globalFilter]="gb" [filterDelay]=1000 [value]="tableData" [alwaysShowPaginator]="true" [rowStyleClass]="setStyle" [rows]="rows" [paginator]="paginate" [alwaysShowPaginator]="false" [resizableColumns]="true" tableStyleClass="table-wrap {{rowClass}}"
    [rowsPerPageOptions]="[5,10,20]" expandableRows="{{setExpander}}" [editable]="setEditable" (onRowClick)="handleRowSelect($event)" [lazy]="pagination" [totalRecords]="totalRecords" (onLazyLoad)="loadLazy($event)" [ngClass]="{'paginator-table': pagination}">
    <div *ngFor="let col of tableOptions.columns, let index=index, let odd=odd, let even=even">
        <p-column *ngIf="col.field" [field]="col.field" [header]="col.header" [sortable]="col.sortable" [filter]="col.filter" [editable]="col.editable" [filterPlaceholder]="col.filterPlaceholder" styleClass="{{col.class}}">
            <ng-template let-col let-data="rowData" let-ri="rowIndex" pTemplate="body">
                    <span *ngIf="!col.field.includes('.')" >{{data[col.field]}}</span>
                    <!-- <span *ngIf="col.field.includes('.')">{{data[col.field.split('.')[0]][col.field.split('.')[1]]}}</span> this does not work because field is like x.y-->
                <a *ngIf="col.field === 'ticket'" target="_blank" href={{link}}{{data[col.field]}}><i class="fa fa-external-link" aria-hidden="true"></i></a>
            </ng-template>
        </p-column>
    </div>
</p-dataTable>

【问题讨论】:

  • 你能分享整个p-datatable html 代码和附带的打字稿吗?或者更好的是,创建一个 Plunker ?此外,您应该删除 field 属性的方括号。
  • 如果我把它做成一个平面对象,一切正常,但我怎样才能让它适用于嵌套对象。
  • 能否分享一下相关的打字稿代码?
  • 我在这里遵循与示例相同的代码,但我从后端获得的数据是某些字段的嵌套 obj。对于嵌套的obj,我们可以写car.color之类的吧?

标签: javascript primeng primeng-datatable


【解决方案1】:

PrimeNG DataTable 已弃用,请改用 Table (AKA TurboTable)。 https://www.primefaces.org/primeng-5-2-0-rc1-released-turbotable/

无论如何,您可以按如下方式访问 Data-Table 中的嵌套对象:

<p-table [columns]="cols" [value]="data" ... >
  ...
  // Definition of table body
  <ng-template pTemplate="body" let-rowData let-columns="columns">
    <tr [pSelectableRow]="rowData">
      <td *ngFor="let col of columns">
         <div *ngIf="col.subfield;then nested_object_content else normal_content"></div>
         <ng-template #nested_object_content>
           {{rowData[col.field][col.subfield]}}
         </ng-template>
         <ng-template #normal_content>
           {{rowData[col.field]}}
         </ng-template>
      </td>
    </tr>
  </ngTemplate>
  ...
</p-table>

在你的组件中:

public data = [
{
  field1: {
    subfield1: 'test'
  },
  field2: 'test',
  field3: 'test',
  field4: {
    subfield4: 'test'
  }
}]

this.cols = [
  { field: 'field1', subfield: 'subfield1'},
  { field: 'field2'},
  { field: 'field3'},
  { field: 'field4', subfield: 'subfield4'},
];

我希望这对你有帮助。 :)

【讨论】:

  • 那么该子字段的排序呢?
  • @Harsh 你找到答案了吗?
【解决方案2】:

作为 Bandeeta 关于 TurboTable 的后续内容:此解决方案可以处理多个嵌套属性,而不仅仅是一个子字段:

<tr [pSelectableRow]="row">
  <td *ngFor="let col of columns">
    <span>{{ getCellData(row, col) }}</span>
  </td>
</tr>

在你的组件中:

getCellData(row: any, col: any): any {
   const nestedProperties: string[] = col.field.split('.');
   let value: any = row;
   for (const prop of nestedProperties) {
     value = value[prop];
   }

   return value;
 }

【讨论】:

  • 很好...只是为了避免空引用访问,您可以替换为 >> value = value ?价值[道具] : '';
  • 是的,但这不适用于可编辑绑定(即 ngModel)
【解决方案3】:

您可以使用 Angular 自定义管道来做到这一点。示例在这里。

app.component.html

<p-table [columns]="cols" [value]="cars">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{col.header}}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowData let-columns="columns">
        <tr>
            <td *ngFor="let col of columns">
                    {{rowData|field:col}}
            </td>
        </tr>
    </ng-template>
</p-table>

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  cars = [
    {
      year: 2019,
      brand: {
        name: "Toyota"
      },
      color: "White",
      passengers: [
        {
          name: "John"
        }
      ]
    },
    {
      year: 2018,
      brand: {
        name: "Toyota"
      },
      color: "White",
      passengers: [
        {
          name: "Suzanne"
        }
      ]
    },
    {
      year: 2017,
      brand: {
        name: "Toyota"
      },
      color: "White",
      passengers: [
        {
          name: "Gökhan"
        }
      ]
    }
  ];
  cols: any[];
  constructor() {}

  ngOnInit() {
    this.cols = [
      { field: "year", header: "Year" },
      { field: "brand.name", header: "Brand" },
      { field: "color", header: "Color" },
      { field: "passengers.0.name", header: "Passengers" }
    ];
  }
}

运行示例在这里。

https://stackblitz.com/edit/angular6-primeng-qhxptl

【讨论】:

  • 工作就像一个魅力,stackblitz 演示正是我正在寻找的。感谢@gkhnclk 提供一个简单的解决方案
【解决方案4】:

有一篇很棒的文章介绍了如何以类型安全的方式执行此操作here,但如果安全不是问题,您可以使用 Lodash 的 get 函数,这样就不必偏离 PrimeNG 基本表的使用带有疯狂的子领域的东西。

// in .ts file
import {get} from 'lodash';

// give it a different name if you like
_ = get;

// columns
this.columns = [
    {field: 'user.address.postcode', header: 'Post Code'}
]

然后在html中

<p-table [columns]="columns" [value]="users$ | async" styleClass="p- 
datatable-sm">
<ng-template pTemplate="header" let-columns>
<tr>
  <th *ngFor="let col of columns">
    {{col.header}}
  </th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr>
  <td *ngFor="let col of columns">
    {{_(rowData, col.field)}}
  </td>
</tr>
</ng-template>
</p-table>

【讨论】:

    【解决方案5】:

    这可能有点晚了,但我最终得到了一些不同的解决方案。我有自己的基于 p-table 的表格组件,我绑定了列、行等。

    我专门为此创建了一个组件,然后绑定当前行和列

    <ng-template pTemplate="body" let-rowData let-columns="columns">
        <tr [pSelectableRow]="rowData">
            <td *ngFor="let col of columns">
              <app-table-column [column]="col" [row]="rowData"></app-table-column>
            </td>
        </tr>
    </ng-template>
    

    这是我的表格列组件,我正在分享一个非常基本的东西,但您可以根据自己的意愿/需要对其进行改进。

    我正在使用 lodash 根据字段(列)获取行的值,它适用于点式(嵌套属性)或平面属性。

        import { Component, Input, OnInit } from '@angular/core';
    import * as moment from 'moment';
    import * as _ from 'lodash';
    
    @Component({
      template: `
        <span>
          {{ value }}
        </span>
      `,
      selector: 'app-table-column',
    })
    export class TableColumnComponent implements OnInit{
    
      @Input() column;
      @Input() row;
    
      value: any;
    
      constructor() {}
    
      ngOnInit(): void {
        this.parseValue(_.get(this.row, this.column.field));
      }
    
      parseValue(value) {
        switch (this.column.type) {
          case 'date':
            this.value = moment(value);
            break;
    
          default:
            this.value = value;
          break;
        }
      }
    
    }
    

    【讨论】:

      【解决方案6】:

      this.cols = [
            { field: 'value1', header: 'Value 1' },
            { field: 'value2', header: 'Value 2', element: true },
          ];
      <td class="" *ngFor="let col of columns">
        <span class="ui-column-title">{{ col.header }} : </span>
        {{col.element ? rowData[col.field].label : rowData[col.field]}}
      </td>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-16
        • 1970-01-01
        • 2019-10-24
        • 2016-05-09
        • 2019-05-18
        • 2021-12-31
        • 1970-01-01
        相关资源
        最近更新 更多