We are trying to use a <p-column *ngFor="let col of cols" ... to display a dynamic number of columns, and also trying to use a <template pTemplate ... to specify how a cell is being rendered.
We try to do it this way:
<p-column *ngFor="let col of cols" [field]="col.field" [header]="col.header | translate" [sortable]="true">
<template let-row="rowData" pTemplate>
<span>{{row[col.field] | mypipe}}</span>
</template>
</p-column>
This results in only a single row being rendered which only has the first column/cell written.
Is there any working way to get a dynamic number of columns with rendering a cell using an Angular 2 pipe?
Environment:
Sorry, was a mistake at our side. Everything is working exactly like it should. The problem was that col.field was a string that contained _dots_ for selecting sub-properties. This was supported inherently by the datatable, but had to be programmed manually when using a normal JavaScript property lookup in the template via Angular's handlebars.
@dereklin Sure. The easiest solution in this case was just implementing a custom Angular 2 Pipe which does the dot-into interpretation with a pipe argument being the selector string.
This is the relevant portion of the template we are currently using:
<p-column ...>
<template let-row="rowData" pTemplate type="body">
<span>{{row | extractProperty:col.field}}</span>
</template>
</p-column>
You see here we are simply using a custom Angular 2 Pipe called "extractProperty" (in hindsight this could have probably named better).
The definition of the quickly prototyped pipe is as follows:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'extractProperty'})
export class ExtractPropertyPipe implements PipeTransform {
transform(value: any, selector: string): string {
if (!selector) {
throw new Error('missing selector');
}
let dot = selector.indexOf('.');
let context = value;
let rest = selector;
while (dot > 0) {
if (!context) {
throw new Error('no object defined from which a property could be extracted');
}
let beforeDot = rest.substr(0, dot);
context = context[beforeDot];
rest = rest.substr(dot + 1);
dot = rest.indexOf('.');
}
if (!context) {
throw new Error('no object defined from which a property could be extracted');
}
return context[rest];
}
}
I take no responsibility for any crashes/malfunctioning that are due to bugs in that code. :)
@httpdigest Thanks for your example! You responded so quickly. I removed my question because I got what you said in your original post and implemented a simple function for displaying the value:
public displayData(store, key) {
let myKeys = key.split('.');
let value: any = store;
myKeys.forEach((k) => {
value = value[k];
});
return value;
}
@httpdigest Hi, I got the requirement to generate columns dynamically, could you please guide me how to do that?
Hi @XtheWiz , did you get it done ?
@rana3012 Yes, but I have another problem right now :(
Most helpful comment
@dereklin Sure. The easiest solution in this case was just implementing a custom Angular 2 Pipe which does the dot-into interpretation with a pipe argument being the selector string.
This is the relevant portion of the template we are currently using:
You see here we are simply using a custom Angular 2 Pipe called "extractProperty" (in hindsight this could have probably named better).
The definition of the quickly prototyped pipe is as follows:
I take no responsibility for any crashes/malfunctioning that are due to bugs in that code. :)