使用动态字段为 table 创建敲除组件
Create knockout component for table with dynamic fields
我正在尝试为 table 创建一个带有动态行和列的剔除组件。要求是两者兼而有之,行和列都可以有控件。像这样 -
<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
在这里可能对我有帮助,但我不知道如何使用它。关于此的任何样本都将非常有用。
这样的事情怎么样:
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);
这只是我在考虑与您要解决的问题类似的问题时遇到的问题。根据您的使用情况,它可能适合您。
有几点需要注意:
- 如果使用它来创建一个真正的 table,您不能像人们希望的那样在页眉中开始标记并在页脚中关闭它。该问题可能有解决方案,但这只是一次快速尝试。
- 可能不支持缺失data/templates等,但您可以根据需要自定义。
- 使用
-template
元素的子节点,而不是节点本身。显然可以根据需要进行修改。
我正在尝试为 table 创建一个带有动态行和列的剔除组件。要求是两者兼而有之,行和列都可以有控件。像这样 -
<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
在这里可能对我有帮助,但我不知道如何使用它。关于此的任何样本都将非常有用。
这样的事情怎么样:
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);
这只是我在考虑与您要解决的问题类似的问题时遇到的问题。根据您的使用情况,它可能适合您。
有几点需要注意:
- 如果使用它来创建一个真正的 table,您不能像人们希望的那样在页眉中开始标记并在页脚中关闭它。该问题可能有解决方案,但这只是一次快速尝试。
- 可能不支持缺失data/templates等,但您可以根据需要自定义。
- 使用
-template
元素的子节点,而不是节点本身。显然可以根据需要进行修改。