いつko.utils.unwrapObservableを使用するのですか?


114

KnockoutJSを使用していくつかのカスタムバインディングを記述しました。ko.utils.unwrapObservable(item)コードを見て、いつ使用するかはまだわかりませんitemが、その呼び出しは基本的に、監視可能かどうかを確認します。ある場合はvalue()を返し、ない場合は値を返します。カスタムバインディングの作成に関するKnockoutのセクションを見ると、次の構文があります。

var value = valueAccessor(), allBindings = allBindingsAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);

この場合、それらはを介してオブザーバブルを()呼び出しko.utils.unwrapObservableますが、も呼び出します。どちらを使用するか、またはどちらを使用するか、または常に上記のパターンに従って両方を使用する必要があるかどうかを把握しようとしています。

回答:


142

ko.utils.unwrapObservableオブザーバブルが与えられているかどうかわからない場合に使用してください。これは通常、監視可能または監視不可能をバインドできるカスタムバインディングにあります。

上記のコードでは、への呼び出しvalueAccessor()は実際にはオブザーバブルをアンラップしていません。正しいコンテキストでバインディングに渡された値を取得するだけです(それを保護するために関数にラップされます)。の戻り値はvalueAccessor()、監視可能である場合とそうでない場合があります。これはバインディングに渡されたものです。


4
それは本当に状況次第です。一部のカスタムバインディングはオブザーバブルでのみ機能するように設計されているため、事前に(ko.isObservable)でオブザーバブルであることを確認してから、()で自由にアンラップできます。オブザーバブルがネストされている可能性のあるオブジェクトを受け取っている場合は、ラップされていないバージョンのオブジェクトを取得してウィジェットまたはサードパーティのライブラリに渡そうとする場合ko.toJS(yourObject)は、を使用するよりもを使用した方がよいko.utils.unwrapObservableでしょう。一般に、ko.utils.unwrapObservableオブザーバブルと非オブザーバブルをサポートするために使用するのが最も安全 です。
RP Niemeyer 2012年

2
私は目的が何であるかと混同していると思いko.utils.unwrapObservableます。コードを見ると、それが観測可能かどうかを確認するだけであり、観測可能である場合は、Knockoutが呼び出し()て観測可能の値を取得します。それ以外の場合は、観測不可能の値を返します。興味があるのは、バインディングに渡されたデータの値だけである場合、なぜ常に使用できないの()ですか?
2012年

17
バインディングでオブザーバブルまたは非オブザーバブルが渡されるかどうかはわかりません。私が持っているmyBindingと言いdata-bind="myBinding: myValue"ます。 myValueオブザーバブルである場合もあれば、ビューモデルのプレーンプロパティである場合もあります。それが単なるプロパティであり、関数のように呼び出すと、エラーが発生します。 ko.utils.unwrapObservableオブザーバブルが渡されたかどうかに関係なく、安全に値を返します。
RPニーマイヤー、2012年

10
「ko.utils.unwrapObservable」は非常に長い式であるため、「ko.unwrap」の省略形を使用することもお勧めします。
Ivan Nikitin 14年

3
@IvanNikitin-確かに、ko.unwrap3.0以降で利用可能であることを指摘したかっただけです。3.0より古いものを使用している場合ko.utils.unwrapObservableは、まだそこにあります。
RPニーマイヤー2014年

12

以前の答えは正しいですが、多くの場合、関数をカスタムバインディングに渡します(アクセス許可をチェックしたり、何かに基づいて何をするかを決定する関数など)。私が本当に必要だったのは、たとえそれが観察可能でなくても、関数をアンラップすることでした。

以下は、すべてを再帰的にアンラップします。

ko.utils.unwrapFunction = function (func) {
    if (typeof func != 'function') {
        return func;
    }
    else {
        return ko.utils.unwrapFunction(func());
    }
};

これが私が書いた簡単なカスタムバインディングの例です:

//replaces single and double 'smart' quotes users commonly paste in from word into textareas and textboxes with normal text equivalents
//USAGE:
//data-bind="replaceWordChars:true
//also works with valueUpdate:'keyup' if you want"

ko.bindingHandlers.replaceWordChars = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var bindingValue = ko.utils.unwrapFunction(valueAccessor);

        if (bindingValue) {
            $(element).val(removeMSWordChars(allBindingsAccessor().value())); //update DOM - not sure why I should need to do this, but just updating viewModel doesn't always update DOM correctly for me
            allBindingsAccessor().value($(element).val()); //update viewModel
        }
    }
}

このように、bindingValueには常に値が含まれています。関数、オブザーバブル、値、またはオブザーバブル内の関数を渡したかどうかについて心配する必要はありません。これにより、必要なオブジェクトに到達するまですべてが適切に展開されます。

それが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.