Как использовать вручную скомпилированный шаблон из репитера?

Я создаю пользовательскую структуру сетки данных для приложения Aurelia в стиле LOB, и мне нужна помощь с тем, как создать шаблон основного элемента сетки, чтобы он мог выбирать пользовательские шаблоны ячеек из дочерних элементов столбца для визуализации.

Это то, что я сделал до сих пор:

Сетка-example.html

<data-grid items-source.bind="rowItems">                    
    <data-column property-name="Name" t="[displayName]fields_Name">
        <div class="flex -va-middle">
            <div class="user-avatar avatar-square">
                <img
                    if.bind="row.dataItem.avatarUri" 
                    src.bind="row.dataItem.avatarUri" />
            </div>

            <span class="name">${row.dataItem.name}</span>
        </div>
    </data-column>

    <data-column property-name="StatusText" t="[displayName]fields_Status">
        <span class="label ${row.statusClass}">${row.dataItem.statusText}</span>
    </data-column>

    <data-column property-name="Location" t="[displayName]fields_Location">
        <span>${row.dataItem.location}</span>
    </data-column>

    <data-column property-name="DateCreated" t="[displayName]fields_MemberSince">
        <span tool-tip.bind="row.dataItem.dateCreated | dateToString:'long-date-time'">
            ${row.dataItem.dateCreated | dateToString:'short-date'}
        </span>
    </data-column>   
</data-grid>

данных-column.ts

import {
    autoinject,
    bindable,
    noView,
    processContent,
    ViewCompiler,
    ViewFactory } from "aurelia-framework";
import { DataGridCustomElement } from "./data-grid";

@autoinject
@noView
@processContent(false)
export class DataColumnCustomElement {
    @bindable
    propertyName: string;

    @bindable
    displayName: string;

    cellTemplate: ViewFactory;

    constructor(private readonly _element: Element,
                private readonly _dataGrid: DataGridCustomElement,
                private readonly _viewCompiler: ViewCompiler) {
        this.cellTemplate = this._viewCompiler.compile(`<template>${this._element.innerHTML}</template>`);
        this._dataGrid.columns.push(this);
    }
}

данное grid.html

<template>
    <div class="table-wrapper -data-list -sticky-header">
        <table class="hover unstriped">
            <tbody>
                <tr class="labels">
                    <th repeat.for="column of columns">
                        <span>${column.displayName}</span>
                    </th>
                </tr>
                <tr repeat.for="row of itemsSource">
                    <td repeat.for="column of columns">
                        <!-- inject view for column.cellTemplate here? -->
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

данных-grid.ts

import { autoinject, bindable } from "aurelia-framework";
import { DataColumnCustomElement } from "./data-column";

@autoinject
export class DataGridCustomElement {
    @bindable
    itemsSource: any[] = [];

    columns: DataColumnCustomElement[] = [];

    constructor(private readonly _element: Element) {
    }
}

data-column элементы объявляют шаблон ячейки, который анализируется вручную в ViewFactory экземпляр - то, что я застрял на том, как использовать шаблон ячейки для каждого столбца данных в соответствующем td ретранслятор в data-grid шаблон, поэтому он ведет себя так, как если бы я прямо объявил содержимое шаблона там.

Можно ли это сделать по умолчанию repeat.for синтаксис? Или мне нужен собственный контроллер шаблона для этого, который может дополнительно принять экземпляр ViewFactory в качестве связываемого параметра из области?

Если есть лучший способ выполнить это требование, я тоже открыт для этого.

1 ответ

Решение

По сути, вы пытаетесь скомпилировать + визуализировать динамический HTML. В этом нет ничего особенного repeat.for или таблицы, но в зависимости от того, что вы пытаетесь достичь, это обычно немного сложнее, чем просто прохождение HTML через viewCompiler,

Вы можете увидеть пример в плагине, который я написал: https://github.com/aurelia-contrib/aurelia-dynamic-html/

Я бы, вероятно, либо использовал этот плагин (или просто скопировал + вставил код и настроил / оптимизировал его под ваши нужды), а затем, сохранив остальную часть кода, как есть, сделал бы что-то вроде этого:

данных-column.ts

this.cellTemplate = this._element.innerHTML; // just assign the raw html

данное grid.html

<tr repeat.for="row of itemsSource">
    <td repeat.for="column of columns"
        as-element="dynamic-html"
        html.bind="column.cellTemplate"
        context.bind="row[column.propertyName]">
    </td>
</tr>

В любом случае, вы упростите это для себя, если будете использовать пользовательский элемент, подобный этому, или в какой-либо другой форме. Изготовить собственный репитер будет очень сложно;)

Другие вопросы по тегам