如何在敲除自定义绑定中设置基于字符串/命名的模板? [英] How to set string-based/named template in a knockout custom binding?
问题描述
我有一个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>
传递给myWidget
的name
也将传递给template
并被拾取.当然,您也可以对传递给template
的init
和update
的内容进行微调,但是对于您提供的上下文来说,就足够了.
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屋!