如何在敲除自定义绑定中设置基于字符串/命名的模板? [英] How to set string-based/named template in a knockout custom binding?

查看:54
本文介绍了如何在敲除自定义绑定中设置基于字符串/命名的模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个bindingHandler(例如myWidget),我希望它根据关联的视图模型中的属性来设置命名模板.我目前已通过在绑定中添加处理程序来实现此目的:

I have a bindingHandler (e.g. myWidget) and I'd like it to set the named template based on properties in the associated view model. I've currently implemented this by adding a handler to the binding:

ko.bindingHandlers.myWidget = {

    template: function (viewModel) {
        // return template name based on viewModel properties
    },

    // init, update etc

然后在前端声明一个ko绑定:

And then in the front end I declare a ko binding:

<div data-bind="myWidget: true, template: ko.bindingHandlers.myWidget.template($data)"></div>

这行得通,尽管我怀疑这样做不是正确"的方法,如果没有其他原因,除非我不添加其他代码来订阅相关的vm属性更改,否则它不会更新模板.

This works, although I suspect it's not the "right" way to do it if for no other reason than it won't update the template without me adding additional code to subscribe to the relevant vm property changes.

有没有办法在update()中设置模板?还是我想念其他东西?

Is there a way to set the template in update()? Or is there something else I'm missing?

推荐答案

您提供的上下文很少,感觉您可能存​​在XY问题.但是直接回答您的问题,如果您希望绑定处理程序将创建内容的时间推迟到内置的template绑定中,建议您复制

You've provided little context, and it feels like you may have an XY-problem. But answering your question straight up, if you want your binding handler to defer creating the content to the built-in template binding, I suggest copying the foreach binding's approach and do it like this:

"use strict";

ko.bindingHandlers.myWidget = {
    'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        return ko.bindingHandlers['template']['init'](element, valueAccessor);
    },
    'update': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        return ko.bindingHandlers['template']['update'](element, valueAccessor, allBindings, viewModel, bindingContext);
    }
}

function RootViewModel() {
  var self = this;
  self.obs = ko.observable("a");
}

ko.applyBindings(new RootViewModel());

pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<script type="text/html" id="a">Ahh, Template</script>
<script type="text/html" id="b">Bee, Template</script>

<div data-bind="with: obs">
  <div data-bind="myWidget: { name: $data }"></div>
</div>

Change obs: <select data-bind="options: ['a', 'b'], value: obs"></select>

<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

传递给myWidgetname也将传递给template并被拾取.当然,您也可以对传递给templateinitupdate的内容进行微调,但是对于您提供的上下文来说,就足够了.

The name you pass to myWidget will also be passed on to template and be picked up. Of course you could fine-tune what you pass to the init and update of template as well, but for the context you had provided the above will suffice.

这篇关于如何在敲除自定义绑定中设置基于字符串/命名的模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆