Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@MKGaru

knockoutのcustom-binding

この記事は、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制御文なので説明は省きます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?