我使用以下html作为模板来构建表(这实际上是Knockout的simpleGrid模板):
<script type='text/html' id='template'>
<table class="table table-bordered table-condensed" >
<thead>
<tr class="active" data-bind="foreach: columns">
<th data-bind="text: headerText"></th>
</tr>
</thead>
<tbody data-bind="foreach: data">
<tr data-bind="foreach: $parent.columns">
<td data-bind="text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] "></td>
</tr>
</tbody>
</table>
</script>
这样我就可以使用不同的模型来创建具有不同列的网格。例如(taken from here,有一些更改):
(function () {
// Private function
function getColumnsForScaffolding(data)
{
if ((typeof data.length !== 'number') || data.length === 0)
{
return [];
}
var columns = [];
for (var propertyName in data[0])
{
columns.push({ headerText: propertyName, rowText: propertyName });
}
return columns;
}
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration)
{
this.data = configuration.data;
this.columns = configuration.columns;
}
};
// Templates used to render the grid
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup)
{
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("ko_simpleGrid_grid", "\
<table class=\"table table-bordered table-condensed\" >\
<thead>\
<tr class=\"active\" data-bind=\"foreach: columns\">\
<th data-bind=\"text: headerText\"></th>\
</tr>\
</thead>\
<tbody data-bind=\"foreach: data\">\
<tr data-bind=\"foreach: $parent.columns\">\
<td data-bind=\"text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] \"></td>\
</tr>\
</tbody>\
</table>");
// The "simpleGrid" binding
ko.bindingHandlers.simpleGrid = {
init: function ()
{
return { 'controlsDescendantBindings': true };
},
// This method is called to initialize the node, and will also be called again if you change what the grid is bound to
update: function (element, viewModelAccessor, allBindings)
{
var viewModel = viewModelAccessor();
// Empty the element
while (element.firstChild)
ko.removeNode(element.firstChild);
// Allow the default templates to be overridden
var gridTemplateName = "ko_simpleGrid_grid",
gridFooterTemplateName = "ko_simpleGrid_gridFooter";
// Render the main grid
var gridContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode");
}
};
})();
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
];
var PagedGridModel = function(items) {
this.items = ko.observableArray(items);
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
]
});
};
ko.applyBindings(new PagedGridModel(initialData));
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind='simpleGrid: gridViewModel'> </div>
现在,我希望能够根据模型生成td
元素,但也有一个“常用”td,其中会有一些按钮,类似:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-bordered table-condensed">
<thead>
<tr class="active" data-bind="foreach: columns">
<th>Item Name</th>
<th>Sales Count</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>Well-Travelled Kitten</td>
<td>352</td>
<td>$75.95</td>
<td>
<button type="button" class="btn btn-default" title="Delete">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</td>
</tr>
<tr>
<td>Speedy Coyote</td>
<td>89</td>
<td>$190.00</td>
<td>
<button type="button" class="btn btn-default" title="Delete">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</td>
</tr>
</tbody>
</table>
我需要将哪些内容添加到模板中才能实现?
答案 0 :(得分:1)
最简单的解决方案是为数组中的表格单元格创建虚拟元素绑定,并在下方直接添加其他单元格。例如:
<tbody data-bind="foreach: data">
<tr>
<!-- ko foreach: $parent.columns -->
<td data-bind="text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] "></td>
<!-- /ko -->
<td data-bind="click: $parent.columns.remove.bind($parent)">delete</td>
</tr>
</tbody>
完整摘录:
(function () {
// Private function
function getColumnsForScaffolding(data)
{
if ((typeof data.length !== 'number') || data.length === 0)
{
return [];
}
var columns = [];
for (var propertyName in data[0])
{
columns.push({ headerText: propertyName, rowText: propertyName });
}
return columns;
}
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration)
{
this.data = configuration.data;
this.columns = configuration.columns;
}
};
// Templates used to render the grid
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup)
{
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("ko_simpleGrid_grid", "\
<table class=\"table table-bordered table-condensed\" >\
<thead>\
<tr class=\"active\">\
<!-- ko foreach: columns -->\
<th data-bind=\"text: headerText\"></th>\
<!-- /ko -->\
<th>Action</th>\
</tr>\
</thead>\
<tbody data-bind=\"foreach: data\">\
<tr>\
<!-- ko foreach: $parent.columns -->\
<td data-bind=\"text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] \"></td>\
<!-- /ko -->\
<td>\
<button type=\"button\" class=\"btn btn-default\" title=\"Delete\">\
<span class=\"glyphicon glyphicon-trash\"></span>\
</button>\
</td>\
</tr>\
</tbody>\
</table>");
// The "simpleGrid" binding
ko.bindingHandlers.simpleGrid = {
init: function ()
{
return { 'controlsDescendantBindings': true };
},
// This method is called to initialize the node, and will also be called again if you change what the grid is bound to
update: function (element, viewModelAccessor, allBindings)
{
var viewModel = viewModelAccessor();
// Empty the element
while (element.firstChild)
ko.removeNode(element.firstChild);
// Allow the default templates to be overridden
var gridTemplateName = "ko_simpleGrid_grid",
gridFooterTemplateName = "ko_simpleGrid_gridFooter";
// Render the main grid
var gridContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode");
}
};
})();
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
];
var PagedGridModel = function(items) {
this.items = ko.observableArray(items);
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
]
});
};
ko.applyBindings(new PagedGridModel(initialData));
&#13;
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind='simpleGrid: gridViewModel'> </div>
&#13;
或者,您可以创建RegularCell
和ActionCell
元素的组合数组,并使用template
绑定和动态模板选择器函数在不同类型的模板之间切换。这是well documented on the knockout site。