代码之家  ›  专栏  ›  技术社区  ›  Sam

如何使用转发器手工编译的模板?

  •  1
  • Sam  · 技术社区  · 6 年前

    我正在为一个lob风格的aurelia应用程序构建一个定制的数据网格框架,并且需要关于如何模板化主网格元素的帮助,这样它就可以从子列元素中提取定制的单元格模板进行渲染。

    这就是我迄今为止所做的:

    网格示例.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>
    

    数据列.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);
        }
    }
    

    数据网格.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>
    

    数据网格.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 回复  |  直到 6 年前
        1
  •  1
  •   Fred Kleuver    6 年前

    repeat.for viewCompiler

    https://github.com/aurelia-contrib/aurelia-dynamic-html/

    this.cellTemplate = this._element.innerHTML; // just assign the raw 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>