4

KO の「セミグローバル」変数を定義する方法はありますか?

実際のグローバル スコープや他のテンプレートから離れたまま、コンテキストに関係なく単一の KO テンプレートで変数を使用できるようにしたいと考えています。

目的は、グローバルが特別な構文なしで常にアクセスできるように、$parentを使用せずに、任意のバインド コンテキスト (KO の foreach 内など) でその 1 つのテンプレートでのみ使用できる一連のヘルパー関数を用意することです。以下の例:

// 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 ドキュメントを参照した後、これを見つけました: 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>

私の場合、すべてのテンプレートの読み込み時にカスタム バインディング ラッパーを自動的に適用できるので、これは私にとって素晴らしい解決策のようです!

この方法を試してみて、何か見落としがあった場合はフォローアップを投稿します。私自身の回答をすぐに受け入れることができないため、この質問はしばらくの間未解決のままにしておきます。その間、あなたの解決策を自由に投稿してください。これを解決するためのより多くのアプローチがあると確信しています。

于 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 に答える