2

我在使用带有自定义模板绑定的 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 是模板。

那么如何在我的自定义模板活页夹中将其标记为模板呢?

谢谢。

4

2 回答 2

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/

于 2012-10-31T09:23:39.887 回答
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/ (参见本页注释 7 )

于 2012-10-31T09:21:35.927 回答