Javascript 使用Knockout.js处理动态模板

Javascript 使用Knockout.js处理动态模板,javascript,knockout.js,Javascript,Knockout.js,我正在尝试在Knockout中创建一个表组件,它可以以仍然使用Knockout的方式呈现任意列。我将一个列定义对象数组传递到组件中,并传递一个任意行对象数组。然后,我有一个嵌套的foreach结构,看起来有点像这样: <tbody data-bind="foreach: {data:rows, as:'row'}"> <tr data-bind="foreach: $parent.columns"> <td data-bind="html:renderC

我正在尝试在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”函数在给定行viewModel的上下文的情况下,返回一些要放入单元格中的html

然而,我真正想要的是能够返回单元格的敲除模板。我不想使用
样式的模板,因为它不适合这个特定的应用程序,但我不知道如何将renderCell()的输出作为模板字符串处理

我怎样才能做到像下面这样的事情,并使其工作

<td data-bind="template:{fn: renderCell(row)}"></td>


我希望在renderCell函数的输出中使用其他组件,如和其他绑定

据我所知,每个单元格都需要一个自定义模板。此模板将基于进入绑定的信息。我能想到的让您做到这一点的秘密是一个自定义绑定处理程序:

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;
}
您可以使用一大堆不同的函数来定义不同的模板

在init中,您可以执行以下操作:

var template = "";
switch (valueToDetermineTemplateChange)
{
    case "useThis":
        template = customTemplateOne(dataToBind);
}
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>
或者,您可以利用JavaScripts的关键值功能

var templates = {
    useThis: function () {}
}

var template = templates[valueToDetermineTemplateChange]();
要执行自定义选项,您可以执行以下操作:

var template = "";
switch (valueToDetermineTemplateChange)
{
    case "useThis":
        template = customTemplateOne(dataToBind);
}
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>

但这只适用于表单中的模板。我尝试使用一个函数来返回模板文本而不是脚本标记。谢谢,但同样,它只返回包含模板html的脚本标记的“名称”,而不是模板文本本身。我明白你的意思,我认为你不能使用基于字符串的模板。我想你需要的是一个自定义绑定。我已经更新了答案,它可能不是最接近的东西,但希望能为你指明正确的方向。谢谢。我曾经遇到过自定义绑定,但我认为可以用它来确定模板。我要试一试。现在投票了,如果我能让它工作,我会接受的。无论如何,谢谢你的支持。