2012-03-08 8 views
106

KnockoutJSを使用してカスタムバインディングを作成しました。 ko.util.unwrapObservable(item)コードを見ると、その呼び出しは基本的にitemが観測可能かどうかをチェックします。そうであればvalue()を返し、そうでなければ値を返します。カスタムバインディングの作成に関するノックアウト上のセクションを見てみると、彼らは次の構文を持っている:ko.utils.unwrapObservableをいつ使用しますか?

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

この場合、彼らは()を経由して、観察を呼び出すが、その後もko.utils.unwrapObservableを呼び出します。私はちょうど1つを他のものに対して使用するか、または上記のパターンに従って両方を使用する必要があるかどうかを調べることを試みています。

答えて

135

あなたが観察可能かどうかわからない場合は、ko.utils.unwrapObservableを使用してください。これは、通常、観察可能なものまたは観察不可能なものがそれに拘束されるカスタムバインディングにあります。

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

+0

カスタムバインディングのベストプラクティスを進めてきたパターンもありますか? – arb

+4

本当に状況によって異なります。いくつかのカスタムバインディングは、オブザーバブルでのみ動作するように設計されているため、フロント(ko.isObservable)でオブザーバブルであることを確認してから、自由にアンラップすることができます()。 Observableがネストされているオブジェクトを受け取っている場合は、オブジェクトのアンラップしたバージョンを取得しようとしている場合は、 'ko.utils.unwrapObservable'を使用するのではなく、' ko.toJS(yourObject) 'を実行する方が良いでしょうウィジェットやサードパーティライブラリに渡すことができます。一般的に、 'ko.utils.unwrapObservable'を使用して、オブザーバブルとノンオブザーバブルをサポートするのが最も安全です。 –

+2

私は 'ko.utils.unwrapObservable'の目的が混乱していると思います。コードを見ると、それは観測可能かどうかをチェックし、そうであればKnockoutは '()'を呼び出してオブザーバブルの値を取得し、そうでなければ観測できない値を返します。私が興味を持っているのは、バインディングに渡されたデータの価値です。どうして私はいつも '()'を使うことができませんか? – arb

9

これまでの回答は正しいですが、カスタムバインディング(権限をチェックしたり、何かに基づいて何をすべきかなどを決定する関数)に関数を渡すことがよくあります。私が本当に必要としたのは、たとえそれが観測可能ではないとしても、関数をアンラップすることでした。

//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は常に値が含まれています。ここでは

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

私が書いた結合単純なカスタムの一例である:以下

再帰的にすべてがアンラップします。私は、関数、オブザーバブル、値、またはオブザーバブル内の関数さえ渡しても心配する必要はありません。これは、私が望むオブジェクトに到達するまで、すべてを適切にアンラップします。

誰かを助ける希望。

+9

私は何も上書きしていない、unwrapObservableはまだそこにあります、私はunwrapFunctionと呼ばれています。 ko.utilsはノックアウトユーティリティ関数なので、これが入るための論理的な名前空間です。私はちょっと面倒ですが、マッピングプラグインがkoネームスペースに置かれるのと同じ理由でネームスペースにこれを入れることにしましたが、これはKoには付属していません。 – pilavdzice

関連する問題