web-dev-qa-db-ja.com

ko.utils.unwrapObservableを使用する場合

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

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

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

111
arb

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

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

139
RP Niemeyer

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

以下は、すべてを再帰的に展開します。

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には常に値が含まれます。関数、オブザーバブル、値、またはオブザーバブル内の関数を渡したかどうかを心配する必要はありません。これは、目的のオブジェクトに到達するまで、すべてを適切にアンラップします。

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

11
pilavdzice