有没有办法为KO定义(缺少更好的术语)“半全局”变量?
我想在不考虑上下文的情况下为一个KO模板提供一个变量,同时保持它不受实际全局范围和其他模板的影响。
目标是在不使用 $ parent 的情况下,在任何绑定上下文中(例如在KO的foreach内部)只有一组辅助函数可用,就像全局变量总是可以访问的一样任何特殊的语法。示例如下:
// Template 1 - helpers.foo has been set for this Template or ViewModel
<div data-bind="text:helpers.foo('Works')"></div>
<div data-bind="foreach: someList">
<div data-bind="text:helpers.foo('Context is inside someList. helpers.foo is not available :( ')"></div>
</div>
// Template 2 - helpers.foo is not set for this Template or ViewModel
<div data-bind="text:helpers.foo('Should not work')"></div>
答案 0 :(得分:3)
我还不确定,但我认为我找到了解决方案。在第0次浏览KO文档后,我发现了这个:Supplying additional values to descendant bindings。
对于那些你的人;博士: 我可以使用该自定义绑定处理程序将任何变量暴露给每个子上下文中的模板,这正是我所寻找的。换句话说,这成为可能:
<强>视图模型强>
<script>
ViewModel = {
Helpers: {
foo: function(message) {return message;}
},
someList: [
'foo',
'bar',
'baz'
]
}
</script>
<强> HTML 强>
<div data-bind="text:helpers.foo('Helpers.foo can be used because we are in the root context')"></div>
<div data-bind="foreach: someList">
<div data-bind="text:helpers.foo('We are in the context of someList. This will fail.')"></div>
</div>
<div data-bind="withProperties:{Helpers:Helpers}">
<div data-bind="foreach: someList">
<div data-bind="text:helpers.foo('Helpers.foo can now be used inside every subcontext, thanks to the withProperties custom binding')"> </div>
</div>
</div>
在我的情况下,自定义绑定包装器可以在加载每个模板时自动应用,所以这对我来说似乎是一个很好的解决方案!
我会试试这种方法并发布一个跟进,如果碰巧我忽略了什么。这个问题将暂时搁置,因为我不能这么快就接受我自己的答案。同时随意发布您的解决方案,我相信有更多方法可以解决这个问题。
答案 1 :(得分:2)
您应该定义从“助手”中获取值的新自定义绑定。仅举几个例子:
// your "semi-globally" accessible helpers
var helpers = {
foo: function(text){ return "<b>" + text + "</b>"; },
boo: function(text){ return "<u>" + text + "</u>"; }
};
// custom binding
ko.bindingHandlers.helpers = {
init: function(element, valueAccessor) {
var opts = valueAccessor();
element.innerHTML = helpers[opts.name].apply(element, opts.args);
}
};
// two different primitive ViewModels without any ref to helpers
function VM_1 () { this.name = "vm-1"; }
function VM_2 () { this.name = "vm-2"; }
// binding models
ko.applyBindings(new VM_1, document.getElementById("vm-1"));
ko.applyBindings(new VM_2, document.getElementById("vm-2"));
HTML:
<div id="vm-1">
<span data-bind="text: name"></span>
<span data-bind="helpers: { name: 'foo', args: ['Works!'] }"></span>
</div>
<div id="vm-2">
<span data-bind="text: name"></span>
<span data-bind="helpers: { name: 'foo', args: ['Works perfectly!'] }"></span>
</div>