2

I have a table component which takes an input JSON for the table format and another JSON for the data. My question is, when my table is rendered with *ngFor, how do I call cellFunction?

My table format JSON:

tblFormat= [
        { headerTxt: 'Order ID', df: 'Order_ID', color: 'blue', cellFunction: 'testME1' },
        { headerTxt: 'Buyer Name', df: 'name', color: 'blue',cellFunction: 'testME2' }
]

My Component

import { Component, AfterViewInit, ViewChild, Input } from '@angular/core';

@Component({
    selector: 'table-comp',
    template: `<table class="table table-hover">
    <thead>
        <tr>
            <th *ngFor="let h of tableInfo"  [style.color]="h.color">{{h.headerTxt}}</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let d of data">
            <td *ngFor="let c of tableInfo" [style.color]=" how do I? c.cellFunction()">
                {{d[c.df]}}
            </td>
        </tr>
    </tbody>
 </table>`
    inputs: ['data','tableInfo']
})

export class TableComp {
    tableInfo=[];
    data=[];
} 
baao
  • 71,625
  • 17
  • 143
  • 203
Thaison Nguyen
  • 131
  • 1
  • 10

2 Answers2

0

Depends mainly on where TestME1 and TestME2 are defined. If it is the TableComp, you can try doing:

 <td *ngFor="let c of tblFormat" [style.color]="this[c.cellFunction]()">

If the functions are defined somewhere else, you just need to replace this with the Object where it is defined.

For example, you can have a service with all the color functions which you inject to the component:

class TableComp {
    constructor(public colorFunctions: ColorFunctions) {}
}

If you have a service like that, you can do:

<td *ngFor="let c of tblFormat" [style.color]="colorFunctions[c.cellFunction]()">

Actually, I have no idea what you are actually trying to do!

sabithpocker
  • 15,274
  • 1
  • 42
  • 75
  • i'm trying to think how i would call it if the cellfunciton is defined in parent component – Thaison Nguyen May 10 '18 at 17:18
  • Why not move them to a service, that can be injected anywhere, is there any dependancy on parent on how the color values are resolved? Can you provide an example color resolver function with ParentComponet code? – sabithpocker May 10 '18 at 17:23
  • Injecting parent to the child as a reference is not something anyone would recommend. [Read this](https://stackoverflow.com/questions/34540615/how-do-i-inject-a-parent-component-into-a-child-component) – sabithpocker May 10 '18 at 17:27
-1

I have made this work, please check this link -> https://stackblitz.com/edit/angular-xwsq2a

Add colorChose method in component, and update template like this,

<td *ngFor="let c of tblFormat" [style.color]="colorChose(c.cellFunction)">

In component, in colorChose method

colorChose (param) {
  return this.executeFunctionByName(param, this);  
}

Create the executeFunctionByName method in the same component. This is used to call function when you know the function name as string.

executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

I hope you have methods mentioned in cellFunction, in this case testME1, which returns color name,

testME1 () {
  return "red";
}

Hope it helps...

Basavaraj Bhusani
  • 5,375
  • 2
  • 16
  • 24
  • why would colorChose not just be "this[param].bind(this)()" instead of all that mess ;) – Patrick Kelleter May 11 '18 at 18:30
  • @patrick, yes, statement you have mentioned it works just fine. The method `executeFunctionByName` handles more scenarios, so I thought it's better to include that as whole. – Basavaraj Bhusani May 12 '18 at 18:43
  • what scenarios do you mean? i can not think of any, which isn't handled by the statement i've mentioned – Patrick Kelleter May 13 '18 at 10:15
  • @patrick, The one scenario is using `namespace` in function_name parameter for `executeFunctionByName`, i.e. `some_object.function_name` in parameter. i.e. `this.executeFunctionByName(some_object.function_name, this); `. The function that should be executed in context of `some_object`. This function takes care of such scenarios, but this is not the case with respect to this question, though. – Basavaraj Bhusani May 13 '18 at 19:41