2013-02-18 25 views
4

是否有任何方法可以爲KO定義(缺少更好的術語)「半全局」變量?Knockout.js模板範圍內的半全局變量

我想讓一個變量可用於單個KO模板,而不管上下文是什麼,同時保持實際的全局範圍和其他模板。

的目標是有一組輔助功能,如果不使用$父只適用於在任何有約束力的情況下(例如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> 

回答

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/

+0

這是我目前的後備解決方案。不理想,因爲助手將在模板之間共享,但有些作品。我會等待一些其他答案,如果沒有其他的工作,我會接受你的答案。 – jpeltoniemi 2013-02-18 21:20:11

+0

對不起,我似乎還沒有理解你的問題。我以爲你想在不同模型之間分享一些變量,而不是在一個模型的上下文之間。 :) – 2013-02-19 06:37:45

+0

沒問題。我也可以在這個問題上表達自己更好:) – jpeltoniemi 2013-02-19 13:05:21

3

我不知道,但是我想我找到了解決辦法。在第N次瀏覽KO文檔後,我發現這個:Supplying additional values to descendant bindings

對於那些你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> 

在我的情況下,自定義綁定的包裝可以自動根據負載對每個模板可以應用,所以這對我來說似乎是一個很好的解決方案

我會嘗試這種方法,併發布後續行動,如果它發生,我忽略了一些東西。這個問題將暫時公開一段時間,因爲我不能很快接受我自己的答案。同時隨時發佈您的解決方案,我相信有更多的方法來解決這個問題。