0

Some background, if you want to skip to the real question, scroll down :-).

I have two arrays of objects One defining fields to be shown in an table, and one that defines each row with each field as well as some metadata, in this case inputs

headers = [
    {
        field: 'a'
    },
    {
        field: 'b'
    }
]

rows = [
    {
        a: "foo", 
        b: "bar", 
        inputs: false
    },
    {
        a: "foo",
        b: "bar", 
        inputs: true
    }
]

Each object in rows will be iterated, as well as each object in headers

<table>
    <tr *ngFor="let row of rows">
        <td *ngFor="let cell of headers" [innerHtml]="row[cell.field]">
        </td>
    </tr>
</table>

As long, all is fine. But if I want dynamic input fields depending on row.inputs value - how should that be solved?

using two sets of <td> with *ngIf="row.inputs" (and vice versa) gives me this error:

Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *...

That's a bummer, but I get it.

The question

In the best of worlds, I would want to use a function in for the innerHtml, which returns an Input Component, but how would that look like?

For example:

In my Component i add a function called getDataOrInput

  getDataOrInput(row, field): string | HTMLElement {
    if(row.inputs){
        /* 
        * Generate a Component based on field, and return HTML ?  
        */
    } else {
        return row[field]
    }
}

And in the HTML

<table>
    <tr *ngFor="let row of rows">
        <td *ngFor="let cell of headers" 
            [innerHtml]="getDataOrInput(row,cell.field)">
        </td>
    </tr>
</table>
Marcus Brunsten
  • 575
  • 5
  • 22

2 Answers2

0

There is an easy workaround for your error message *ngIf and *ngFor on same element causing error

An alternative approach for dynamic components is explained in Angular 2 dynamic tabs with user-click chosen components

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

If you want to generate a component based on a field your best bet might be to create a structural directive.

for example:

const factory = this._resolver.resolveComponentFactory(**SomeComponent**);

// Make the Component with a factory and index (tells angular where to place component)

const componentRef = this._viewContainer.createComponent(factory, i);

// then you can tap into the instance of that component like so:
componentRef.instance.[**SomeInputName**]
Snackdex
  • 674
  • 8
  • 18