4

有没有办法为 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>
4

2 回答 2

3

我还不确定,但我想我找到了解决方案。在第 n 次浏览 KO 文档后,我发现了这一点:为后代绑定提供附加值

对于那些 tl;dr 的人:我可以使用该自定义绑定处理程序在每个子上下文中向模板公开任何变量,这正是我所寻找的。换句话说,这成为可能:

视图模型

<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>

在我的情况下,自定义绑定包装器可以在加载每个模板时自动应用,所以这对我来说似乎是一个很好的解决方案!

如果发生我忽略了某些事情,我会尝试这种方法并发布后续内容。这个问题将暂时开放,因为我不能这么快接受自己的答案。同时随时发布您的解决方案,我相信有更多的方法可以解决这个问题。

于 2013-02-18T23:26:23.023 回答
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>

http://jsfiddle.net/ostgals/GfBJ9/1/

于 2013-02-18T20:21:01.067 回答