我试图在Knockout中创建一个表组件,它可以以仍然使用Knockout来获取单元格内容的方式呈现任意列。我将一个列定义对象数组传递给组件和一个任意行对象的数组。然后,我有一个嵌套的foreach结构,看起来有点像这样:
<tbody data-bind="foreach: {data:rows, as:'row'}">
<tr data-bind="foreach: $parent.columns">
<td data-bind="html:renderCell(row)"></td>
</tr>
</tbody>
有了这个,我可以允许'renderCell&#39;给定行viewModel的上下文,每个列的函数返回一些html进入单元格。
然而,我真正想要的是能够返回单元格的Knockout模板。我不想使用<script type="text/html" id="xyz">
样式模板,因为它不适合这个特定的应用程序,但我无法弄清楚如何让Knockout将renderCell()的输出视为模板字符串。
我如何做以下的事情并使其有效?
<td data-bind="template:{fn: renderCell(row)}"></td>
我想在renderCell函数的输出中使用其他组件和其他绑定。
答案 0 :(得分:1)
据我了解,您需要为每个单元格定制一个模板。此模板将基于进入绑定的信息。我能想到让你这样做的壁橱是一个自定义绑定处理程序:
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
}
};
这是淘汰文档中的基本内容。我猜想在init函数中你可以选择一些你想要显示的html:
function customTemplateOne(dataToBind) {
var spanEl = document.createElement('span');
spanEl.innerHTML = dataToBind;
return spanEl;
}
您可以拥有一大堆不同的功能来定义不同的模板。
在你的初始化中你可以这样做:
var template = "";
switch (valueToDetermineTemplateChange)
{
case "useThis":
template = customTemplateOne(dataToBind);
}
或者您可以利用JavaScripts键值。
var templates = {
useThis: function () {}
}
var template = templates[valueToDetermineTemplateChange]();
要进行自定义选项,您可以执行以下操作:
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
var options = {};
ko.extend(options, ko.bindingHandlers.yourBindingName); // get the global options
ko.extend(options, ko.unwrap(valueAccessor())); // merge with the local options
// so if you have a data property on the options which holds the ko binding you can do this:
var data = ko.unwrap(options.data);
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
},
options: {
customOption: "Some Option"
}
};
<div data-bind="yourBindingName: { data: someValue }"></div>
而不是applyBindingsToDescendants
函数,使init成为其他绑定的包装:
ko.applyBindingsToNode(element, { html: valueAccessor() }, context); // the html is a binding handler, you can specify with, text, foreach....