knockoutjs - 自定义模板与父内容绑定

时间:2012-10-31 09:06:33

标签: templates knockout.js

我在使用自定义模板绑定的knockoutjs时遇到问题。

假设我有一个像这样的HTML主体:

<div id="1">
    <div data-bind="template:{name: '2', data: data}"></div>
</div>

<div id="2">
    <h3 data-bind="text: caption"></h3>
</div>

JS代码如下所示:

var ViewModel2 = function () {
    this.caption = ko.observable("Caption");
}

var ViewModel1 = function () {
    this.data = new ViewModel2();
}

ko.applyBindings(new ViewModel1(), document.getElementById("1"));

如果我们测试这段代码,一切都会正常工作;
请参阅JSFiddle示例:http://jsfiddle.net/4eTWW/33/

现在假设我们想要进行自定义模板绑定。我们将使用'templatex'绑定而不是'template'。

在HTML中,我们只需更改一行:

<div data-bind="templatex:{name: '2', data: data}"></div>

接下来,让我们为JS添加自定义模板绑定:

/*Custom binding*/
ko.bindingHandlers.templatex = {
   init: function (element) {
       ko.bindingHandlers.template.init.apply(this, arguments);
   },

   update: ko.bindingHandlers.template.update
}

请参阅:http://jsfiddle.net/4eTWW/35/

但是在这种情况下我们有一个错误,说它在模型中找不到“标题”。

现在让我们将模板{}添加到html绑定:

<div data-bind="template: {}, templatex:{name: '2', data: data}"></div>

请参阅:http://jsfiddle.net/4eTWW/36/

现在一切正常。

似乎在绑定父div时,它无法确定子div是模板。

那么如何在自定义模板绑定器中将其标记为模板?

感谢。

2 个答案:

答案 0 :(得分:1)

你有错误的更新处理程序,改为:

ko.bindingHandlers.templatex= {
    init: function(element) {
        // do things
        return ko.bindingHandlers.template.init.apply(this, arguments);
    },

    update: function(element) {
        return ko.bindingHandlers.template.update.apply(this, arguments);
    }
}

这是工作小提琴:http://jsfiddle.net/vyshniakov/4eTWW/39/

答案 1 :(得分:0)

我认为您不能使用自定义绑定来创建新的模板引擎。您需要使用ko.setTemplateEngine()注册自定义引擎。

来自knockoutjs来源:

If you want to make a custom template engine,

[1] Inherit from the ko.templateEngine class (like ko.nativeTemplateEngine does)
[2] Override 'renderTemplateSource', supplying a function with this signature:

       function (templateSource, bindingContext, options) {
           // - templateSource.text() is the text of the template you should render
           // - bindingContext.$data is the data you should pass into the template
           //   - you might also want to make bindingContext.$parent, bindingContext.$parents,
           //     and bindingContext.$root available in the template too
           // - options gives you access to any other properties set on "data-bind: { template: options }"
           //
           // Return value: an array of DOM nodes
       }

[3] Override 'createJavaScriptEvaluatorBlock', supplying a function with this signature:

       function (script) {
           // Return value: Whatever syntax means "Evaluate the JavaScript statement 'script' and output the result"
           //               For example, the jquery.tmpl template engine converts 'someScript' to '${ someScript }'
       }

    This is only necessary if you want to allow data-bind attributes to reference arbitrary template variables.
    If you don't want to allow that, you can set the property 'allowTemplateRewriting' to false (like ko.nativeTemplateEngine does)
    and then you don't need to override 'createJavaScriptEvaluatorBlock'.

示例:http://jsfiddle.net/6pStz/(参见本page注释7)

相关问题