0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Javascript】Knockout.jsでclickバインディングを使うとcheckedバインディングが機能しなくなる!!【初心者向け】

Last updated at Posted at 2017-08-22

本記事の内容について

Knockout.jsを使い始めた際に引っかかる click + checked についての解説です。
というよりも自分が嵌ったので調べた結果です。

まずはそれぞれ実装してみる

 取り敢えずそれぞれのバインディングを実装してみます。

checkedについて

checked バインディングは ViewModel のプロパティと チェックボックス () や ラジオボタン () などのチェックできるフォーム部品をリンクします。
ユーザが関連付けられたフォーム部品にチェックを入れると、ViewModel の値が更新されます。 反対に、ViewModel の値を変更することでフォーム部品のチェック状態を変更することができます。

参考:Knockout.js 日本語ドキュメント

checkedを実装

test.html
 <label><input type="checkbox" data-bind="checked: isChecked" />テストチェックボックス</label>
test1.js
    var viewModel = {
        isChecked: ko.observable(true) // 最初はチェックされた状態
    };

この実装に関してはKockoutに関して少し調べた方なら特に問題はないと思います。

clickについて

click バインディングは関連付けられた DOM エレメントがクリックされたときに、 指定した JavaScript 関数を実行するイベントハンドラを追加します。 button や input、a などで最もよく使用しますが、 可視エレメントであればなんでも使うことができます。

参考:Knockout.js 日本語ドキュメント

要するに、バインディングされているform部品をクリックしたときにそのイベントハンドラを実行します。

clickの実装

test.html
 <input type="button" data-bind="click: clicked">クリック</input><label data-bind="text: count"></label>
test2.js

var viewModel = {
    count : ko.observable(0),
    clicked : function() {
        var previousCount = this.count ();
        this.count (previousCount + 1);
    }
};

ここも特に問題ないと思う。

clickバインディングとcheckedバインディングを同時に使ってみる

さて、ここまではそれぞれ1つの実装だったので問題はないと思います。では、ここからが本題で2つ同時実装してみようと思います。

まずは普通に実装

test.html
 <label><input type="checkbox" data-bind="checked: isChecked,click:clicked" />テストチェックボックス</label>
<p data-bind="text: isChekd"></p>
test3.js
var viewModel = {
    isChecked: ko.observable(false),
    clicked: function() {
       // 何かしらの処理
    }    
};

 これで実行してみても上手くいかない。clickは動いていると思いますが、checkedが正常に動作していないはずです。

何がダメなのか。原因は??

knockout.jsの日本語ドキュメントを読んでみました。

(注3) デフォルトのクリックの挙動を許可する
通常、Knockout はクリックイベントによるデフォルトの挙動を抑止します。 これは、もし a (リンク)タグに click バインディングを使用した場合、 例えば、ブラウザはハンドラ関数を呼び出すのみでリンク先への遷移は行いません。 通常は click バインディングにてリンクは、ハイパーリンクではなく ViewModel を操作するための UI 部品として使われるためこのような仕様となっています。
もしもクリックイベントのデフォルトの挙動を行わせたい場合は、 click のハンドラ関数にて true を返却してください。

つまり、正しく動作させたい場合は「tureを返せ」ということらしい。

さっそく実装

test3.js
var viewModel = {
    isChecked: ko.observable(false),
    clicked: function() {
       // 何かしらの処理
        return true; // ここを追加
    }    
};

今回はうまく動きましたね。
clickバインディングだけを実装してた時には気にも止めていませんでしたが、しっかりとドキュメントは読んだほうがいいなぁと今回のことで思いました。

参考

0
3
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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?