LoginSignup
0
2

More than 5 years have passed since last update.

knockoutのcustom-binding

Posted at
この記事は、knockout.js Advent Calendar 2015の5日目の記事です。 先に4日目に目を通すことを推奨しています。
knockout , knockout-es5 , knockout.punches環境を想定しています。

knockoutでは、標準で提供されているbindingのほかに、独自でbindingをcustom bindingとして登録することもできます。

custom bindingの作成の一例として、imgタグなどで用いることを想定とした、src属性を設定するbindingを作ってみます。
ちなみに、knockoutのbindingのattrの説明内でで、imgタグのsrcを<img src="http://example.com/{{imgfile}}">としてはいけないのは、何故だか分かりますか?

そうです。src属性はjavascriptによって制御される前に、
ブラウザによって、外部リソースの取得の動作が実行されるため、
http://example.com/{{imgfile}}へのHTTP Get Requestが発生してしまいます。
当然期待するファイルは存在しないので、リクエストエラーになりますし、それは無駄なリクエストです。(ネタ元、関連)

今回作成するcustom-bindingの仕様は次の通りとします。

  • data-bind="src:['http://example.com/',resource]"のように、srcにresourceを解決するための配列を与える。
  • src配列の1要素でも 未解決(undefinedまたはnull)の場合には、resourceを取得しない。

この場合のサンプルはこうなります。

index.html
<img data-bind="src:['http://lorempixel.com/',resource]"/>
script.js
ko.bindingHandlers['src']= {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var src = valueAccessor().map(function(item){return ko.unwrap(item)});
        if(src.indexOf(undefined)==-1 && src.indexOf(null)==-1){
            element.setAttribute('src',src.join(''));
        }else{
            element.removeAttribute('src');
        }
    }
}

Custom Bindingの解説は、(公式日本語)に詳しく書かれています。

ko.bindingHandlers['src']srcという名前のcustom bindingを作成しますよー という宣言です。(最もただの連想配列として拡張しているだけなのですが)
updateは、vallueAccessorの中値が変化したタイミング(および初期化のタイミング)で時効されるハンドラです。
valueAccessor()は、今回の場合は、src:に渡す配列[]を取得しています。それの各要素を ko.unwrap()したものをsrcという変数に代入しているのは、コードを見れば明白ですね。
ko.unwrapは、与えられた引数が、ko.observable()な関数であれば、それを実行した値 そうでなければ そのままの値を返すというヘルパーです。
その他の行は、ただのjavascriptとdom制御文なので説明は省きます。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2