Je suis l'option de modèle donnée dans les documents primeng pour créer un lien avec les données de colonne à côté d'une colonne dateng primeng, mais je ne suis pas en mesure d'afficher un objet imbriqué à l'aide de {{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>
Comment puis-je y parvenir?
Partager tout le code ->
<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>
PrimeNG DataTable est obsolète, utilisez plutôt Table (AKA TurboTable). https://www.primefaces.org/primeng-5-2-0-rc1-released-turbotable/
Quoi qu'il en soit, vous pouvez accéder à un objet imbriqué dans Data-Table comme suit:
<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>
et dans votre composant:
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'},
];
J'espère que ceci vous aide. :)
Pour faire suite à ce que Bandeeta a dit à propos de TurboTable: cette solution peut gérer plusieurs propriétés imbriquées au lieu d'un seul sous-champ:
<tr [pSelectableRow]="row">
<td *ngFor="let col of columns">
<span>{{ getCellData(row, col) }}</span>
</td>
</tr>
Et dans votre composant:
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;
}
Vous pouvez le faire en utilisant Angular Pipe personnalisée. Échantillon ici.
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" }
];
}
}
L'exemple courant est ici.
Cela pourrait être un peu en retard, mais je me suis retrouvé avec une solution un peu différente. J'ai mon propre composant de table basé sur p-table et je lie les colonnes, les lignes, etc.
J'ai créé un composant spécifiquement pour cela, puis je lie la ligne et la colonne en cours
<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>
Ceci est mon composant table-colonne, je partage un truc très basique mais vous pouvez l'améliorer comme vous le souhaitez/besoin.
J'utilise lodash pour obtenir la valeur de la ligne en fonction du champ (colonne), cela fonctionne pour les propriétés en pointillé (propriétés imbriquées) ou plates.
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;
}
}
}