Как задать шаблон для динамических компонентов?

Некоторый фон, если вы хотите перейти к реальному вопросу, прокрутите вниз: -).

У меня есть два arrays objects
Один определяющий поля, которые должны быть показаны в таблице, и один, который определяет каждую строку с каждым полем, а также некоторые метаданные, в этом случае inputs

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

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

Каждый objectrowsвход будет повторяться, а также каждый objectвход headers

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

Пока все в порядке.
Но если я хочу динамические поля ввода в зависимости от row.inputsзначения — как это должно быть решено?

использование двух наборов <td>with *ngIf="row.inputs"(и наоборот) дает мне эту ошибку:

Не может иметь несколько Привязок шаблонов для одного элемента. Используйте только один атрибут с именем ‘template’ или с префиксом *…

Это облом, но я понимаю.

Вопрос

В лучшем из миров я хотел бы использовать функцию для innerHtml, которая возвращает входной компонент, но как это будет выглядеть?

Например:

В my ComponentI добавить функцию под названием getDataOrInput

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

И в HTML

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

2 ответа

  1. Существует простой обходной путь для Вашего сообщения об ошибке * ngIf и * ngFor на том же элементе, вызывающем ошибку

    Альтернативный подход для динамических компонентов объясняется в угловых 2 динамических вкладках с выбранными пользователем компонентами

  2. Если вы хотите создать компонент на основе поля, лучше всего создать структурную директиву.

    например:

    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**]