【AngularJS】ng-modelとng-clickの処理順番の紹介

AngularJS(Angular 1.x系)フレームワークで、チェックボックスにng-modelng-clickの両方を指定すると、フレームワークのバージョンによっては、予期した動作にならないことがあります。

原因は、フレームワークのバージョンによりng-modelng-clickの処理順番が違うためです。正しく動作していた場合でも、フレームワークのバージョンアップにより、正しく動作しないことがあるため注意が必要です。

今回は、ng-modelng-clickの処理順番が変更されるAngularJSフレームワークのバージョン、検証プログラム例、解決方法の紹介をしていきます。

スポンサーリンク

検証環境

検証に使用した環境/ライブラリを次に記載します。

  • Firefoxブラウザ
    • バージョン:84.0(64ビット)
  • AngularJS(Angular 1.x)
    • バージョン:1.3.0、1.3.1、1.6.10、1.7.0

仕様確認

公式サイトのドキュメントからバージョンによる処理順番の仕様を確認してみます。

1.3.0までは、公式サイトのドキュメントでは、ng-modelng-clickの処理順番は、同じ優先順位が記載されています。このため、どちらが先に動作するかは決まっていません。

ng-modelの優先度については、次のように記載されています。

This directive executes at priority level 0.

https://code.angularjs.org/1.3.0/docs/api/ng/directive/ngModel

ng-clickの優先度については、次のように記載されています。

This directive executes at priority level 0.

https://code.angularjs.org/1.3.0/docs/api/ng/directive/ngClick

1.3.1からは、公式サイドのドキュメントでは、ng-modelng-clickの処理順番は、違う優先順位が記載されています。このため、ng-clickng-modelの順番で動作することになります。

ng-modelの優先度については、次のように記載されています。

This directive executes at priority level 1.

https://code.angularjs.org/1.3.1/docs/api/ng/directive/ngModel

ng-clickの優先度については、公式サイトでは次のように記載されています。

This directive executes at priority level 0.

https://code.angularjs.org/1.3.1/docs/api/ng/directive/ngClick

動作検証

チェックボックスにng-modelng-clickの両方を指定して、値を表示するプログラムを作成して動作検証します。

プログラム例は、次のようになります。scriptタグに指定するバージョンを変更して動作確認を実施します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
    <script>
      var app = angular.module("exampleApp", []);
      app.controller("exampleController", function ($scope) {
        $scope.ng_model = false;
        $scope.ng_click = false;
        $scope.onClick = function () {
          $scope.ng_click = $scope.ng_model;
        };
      });
    </script>
  </head>

  <body>
    <div ng-app="exampleApp">
      <div ng-controller="exampleController">
        <div>
          <input type="checkbox" ng-model="ng_model" ng-click="onClick()" />
        </div>
        <div>ng-model:{{ng_model}}</div>
        <div>ng-click:{{ng_click}}</div>
      </div>
    </div>
  </body>
</html>

動作検証したところ、次のバージョンではng-modelng-clickの順番で動作します。

  • 1.3.0
  • 1.3.1

公式ドキュメントでは、バージョン1.3.1からng-clickの処理が先に動作しそうでしたが、予期した結果にはなりませんでした。

動作検証のプログラムの実行例は、次のようになります。ng-modelng-clickの処理順番で動作するため、同じ値が設定されます。

初期表示
チェックボックス選択時表示

バージョンを段階的に最新にして動作検証したところ、次のバージョンでng-clickが先に動作する現象を確認できました。

  • 1.7.0

動作検証のプログラム実行例は、次のようになります。ng-clickng-modelの処理順番で動作するため、違う値が設定されます。

初期表示
チェックボックス選択時表示

動作検証に使用したバージョンと動作をまとめると次のようになります。

バージョン動作
1.3.0ng-modelng-clickの順番で処理を実行します。
1.3.11.3.0と同じ動作になります。
1.6.101.3.0と同じ動作になります。
1.7.0ng-clickng-modelの順番で処理を実行します。
バージョン毎の動作一覧

修正方法

チェックボックスでng-modelng-clickを両方を指定すると、バージョンにより動作が違う結果となるため、ng-clickではなくng-changeを使用することで問題を解決することができます。

動作検証で作成したプログラム例を修正すると、次のようにチェックボックスのng-clickng-changeへ変更することで問題を解決することができます。

<input type="checkbox" ng-model="ng_model" ng-change="onClick()" />

まとめ

チェックボックスにng-clickng-modelの両方を指定するときは、フレームワークのバージョンにより動作が違うことがあります。

参考

フレームワークのバージョン毎の動作例を次で確認することができます。