使用淘汰赛动态构建 HTML

Building HTML dynamically with knockout

我在 C# 的 MVC4 项目中有一个 single-page-application。

在我的 HTML 中,我有一个 like-a-table 列表 - 第一个是 table 标题,第二个是 div 和 "foreach" 属性(敲除)并显示我列表中的所有项目。

现在,我需要这个 "table" 是动态的 - 我将获得列列表和 "instructions"(列标题、列 class 名称、列值名称、css 条件等)和 HTML 将动态构建。 淘汰赛有可能吗?

现在这是我的代码。只有 5 列。我需要它是动态的,这样我就可以通过更改指令列表轻松添加(和删除)列,而无需触及 HTML.

    <ul class="assetsTitles">
        <li class="ItemKey" data-bind="click: sortBy.bind($data, 'Key'), css: { selected: Filter().OrderBy() == 'Key', desc: Filter().Descending() }"><span>Key</span></li>
        <li class="ItemName" data-bind="click: sortBy.bind($data, 'Name'), css: { selected: Filter().OrderBy() == 'Name', desc: Filter().Descending() }"><span>Item Name</span></li>
        <li class="ItemProp1" data-bind="click: sortBy.bind($data, 'ItemProp1'), css: { selected: Filter().OrderBy() == 'ItemProp1', desc: Filter().Descending() }">ItemProp1</li>
        <li class="ItemProp2" data-bind="click: sortBy.bind($data, 'ItemProp2'), css: { selected: Filter().OrderBy() == 'ItemProp2', desc: Filter().Descending() }">ItemProp2</li>
        <li class="ItemProp3" data-bind="click: sortBy.bind($data, 'ItemProp3'), css: { selected: Filter().OrderBy() == 'ItemProp3', desc: Filter().Descending() }">ItemProp3</li>
    </ul>

<div data-bind="foreach: items, visible: items().length > 0">
    <div class="itemRow" data-bind=" attr: { id: RowId() }">
        <ul class="itemRowDetails " data-bind="visible: ShowDetails, selected: IsSelected, click: $parent.showItemDetails.bind($data, $data, $parent.type), css: { selected: IsSelected() }">
            <li class="ItemKey" data-bind=" title: Key"><span data-bind="text: Key" /></li>
            <li class="ItemName" data-bind=" title: Name"><span data-bind="text: Name" /></li>
            <li class="ItemProp1" data-bind=" title: ItemProp1"><span data-bind="text: ItemProp1" /></li>
            <li class="ItemProp2" data-bind=" title: ItemProp2"><span data-bind="text: ItemProp2" /></li>
            <li class="ItemProp3" data-bind=" title: ItemProp3Display"><span data-bind="text: ItemProp3Display, css: { alertDetail: ItemProp3Alert, alertDetail2: ItemProp3Alert2 }" /></li>
        </ul>
    </div>
</div>

你可以使用 ko.renderTemplate 并做一些类似的事情:

  <!-- ko foreach:$root.visibleColumns() -->\
     <li  data-bind=\"attr:{'data-columnname' : columnName}\" role=\"column\" ><span  data-bind=\"attr:{'class': columnHeaderCss, 'data-columnname' : columnName,'data-headertext': headerText}, text: headerText\"></span> </li>\
  <!-- /ko -->\

并将列列表传递给 viewModel :

 ko.dataGrid = {
    viewModel: function (configuration) {
         var me = this;
          $.extend(me, {
            columns: configuration.columns,
             visibleColumns: function () {
                   var res = [];
                    $.each(me.columns, function (i, c) {
                        if (c.visible)
                            res.push(c);
                    });

                return res;
            },
          });
      }

您可以尝试使用传统技术在脚本中构建 html,然后将其附加到元素。然后将其添加到绑定中,该元素的名称需要作为第二个参数包含在内:

ko.applyBindings(viewModel, dynamicElement)

或者 ko 有 html ("html:") 和文本绑定 ("text:") 选项。

在代码中构建 html 时,您可能需要使用 "containerless control flow syntax" 即在注释符号中换行,例如<!-- ko foreach: myItems --> .... <!-- /ko --> 其中 myItems 是一个数组。

关于可能的注入攻击的通常注意事项!

好久没玩ko了..