如何从转发器中使用手动编译的模板?

How to consume manually compiled template from repeater?

我正在为 LOB 风格的 Aurelia 应用程序构建自定义数据网格框架,需要有关如何模板化主网格元素的帮助,以便它可以从子列元素中选取自定义单元格模板进行呈现。

这是我到目前为止所做的:

网格-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 实例作为范围中的可绑定参数?

如果有更好的方法来实现这个要求,那么我也愿意接受。

您实际上是在尝试编译+渲染动态 html。 repeat.for 或表格没有什么特别之处,但是根据您要实现的目标,这通常比简单地通过 viewCompiler 传递 html 要复杂一些。

你可以在我写的插件中看到一个例子:https://github.com/aurelia-contrib/aurelia-dynamic-html/

我可能会使用该插件(或者简单地复制+粘贴代码并 tweak/optimize 它以满足您的需要),然后保持其余代码不变,执行如下操作:

数据-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>

无论如何,如果您只使用像这样的自定义元素或其他形式的自定义元素,您就会使这件事变得更容易。制作自己的中继器 非常 困难 ;)