web-dev-qa-db-ja.com

ネストされたオブジェクトをプライミングの列に表示します

Primengの​​ドキュメントで提供されているテンプレートオプションに従って、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>
6
RemyaJ

PrimeNG DataTableは非推奨です。代わりにテーブル(別名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'},
];

これがお役に立てば幸いです。 :)

15
Bandeeta

BandeetaがTurboTableについて言ったことのフォローアップとして:このソリューションは、1つのサブフィールドだけでなく、複数のネストされたプロパティを処理できます。

<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;
 }
6
Stephanie

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

0
gkhnclk

これは少し遅れるかもしれませんが、私は少し異なる解決策に終わりました。私は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;
    }
  }

}
0
jalex19