使用动态字段为表创建挖空组件

时间:2015-07-31 06:16:26

标签: templates components knockout-3.0 xmltable

我正在尝试使用动态行和列为表创建一个挖空组件。要求是两者,行和列可以有控件。像这样的东西 -

                    <dynamic-table params="data: item">
                        <header-template>
                           <label>Column1</label>
                            <label>Column2</label>
                            <label>Column3</label>
                            <a href="#">Column 4</a>
                        </header-template>
                        <body-template params="showButtons: ['Edit', 'Delete']">
                            <label>FieldValue0</label>
                            <label>FieldValue1</label>
                            <label>FieldValue2</label>
                            <label>FieldValue3</label>
                            <input type="text" value="FieldValue4"></input>
                        </body-template>
                    </dynamic-table>

我正在考虑的方法是使用ko组件为标题和正文创建单独的模板。 $componentTemplateNodes可能会对我有所帮助,但我无法弄明白我如何使用它。任何样本都非常有用。

1 个答案:

答案 0 :(得分:1)

这样的事情怎么样:

JsFiddle

HTML:

<dyno-table params="headerData: { title: title }, rowData: rows">
  <header-template>
    <h2>HELLO! <span data-bind="text: title"></span></h2>
  </header-template>
  <row-template>
    <div>Name: <span data-bind="text: name"></span>, Age: <span data-bind="text: age"></span></div>
  </row-template>
</dyno-table>

<template id='dyno-table-template'>
  <!-- ko template: { nodes: headerNodes, data: headerData } -->
  <!-- /ko -->
  <!-- ko template: { nodes: rowNodes, foreach: rowData } -->
  <!-- /ko -->
  <!-- ko template: { nodes: footerNodes, data: footerData } -->
  <!-- /ko -->
</template>

JavaScript的:

ko.components.register("dyno-table", { 
  viewModel: { createViewModel: createViewModel },
  template: { element: 'dyno-table-template' }
});

function createViewModel(params, componentInfo) {
  var headerNodes = getChildNodes(componentInfo.templateNodes, 'header-template'),
    rowNodes = getChildNodes(componentInfo.templateNodes, 'row-template'),
    footerNodes = getChildNodes(componentInfo.templateNodes, 'footer-template');

  return {
    headerNodes: headerNodes,
    headerData: params.headerData,
    rowNodes: rowNodes,
    rowData: params.rowData,
    footerNodes: footerNodes,
    footerData: params.footerData
  };
}

function getChildNodes(allNodes, tagName) {
    var lowerTagName = tagName.toLowerCase(),
    node = ko.utils.arrayFirst(allNodes, function(node) { return node.tagName && node.tagName.toLowerCase() === lowerTagName; }),
    children = (node ? node.childNodes : null);

  return children;
}

var model = {
  title: ko.observable('A TABLE!'),
  rows: ko.observableArray([
    { name: ko.observable('Max'), age: ko.observable(12) },
    { name: ko.observable('Max2'), age: ko.observable(13) },
    { name: ko.observable('Max3'), age: ko.observable(14) },
    { name: ko.observable('Max4'), age: ko.observable(15) },
    { name: ko.observable('Max5'), age: ko.observable(16) },
    { name: ko.observable('Max6'), age: ko.observable(17) },
  ]),
  farewell: ko.observable('Farewell!')
};

ko.applyBindings(model);

这是我在考虑类似问题时遇到的问题。根据您的使用情况,它可能适合您。

有几点需要注意:

  1. 您无法在标题中启动标记,并在页脚中将其关闭,就像使用它来创建真实表格一样。可能是该问题的解决方案,但这只是一次快速尝试。
  2. 可能不支持缺少数据/模板等,但您可以根据需要进行自定义。
  3. 使用-template元素的子节点,而不是节点本身。显然可以根据需要进行修改。