Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

別ファイルやJavaScriptでメッセージを管理するには?(ng-message-include/ng-message-exp)

2015年7月6日

ng-messages属性で使用するメッセージを、ページ内でテンプレート化したり、外部ファイル化したりして効率的に管理する方法を説明する。

  • このエントリーをはてなブックマークに追加
  • 対象:AngularJS 1.3以降

 別稿「TIPS:式の真偽に応じて表示を切り替えるには?」では、ng-messagesng-message属性を利用することで、検証エラー時にメッセージを表示する方法を紹介しました。本稿では、引き続いてng-messages属性で利用するメッセージを別ファイル(テンプレート/JavaScript)に外部化する方法について解説します。検証メッセージのように、アプリで共通して利用するメッセージについては、個々のテンプレートで毎回準備するよりは、本稿の方法を利用することで再利用でき、メッセージにも統一性を持たせられるでしょう。

メッセージを別ファイルに分離する

 メッセージ情報(=ng-message属性のリスト)は、リスト1に示すように、別ファイルとして切り出すこともできます。

HTML
<span ng-message="required">入力は必須です。</span>
<span ng-message="min, max">
  入力値が小さすぎるか、大きすぎます。</span>
<span ng-message="number">数値で入力してください。</span>
リスト1 別ファイルに切り出したメッセージ情報(messages_template.html)

 別ファイルとして定義したメッセージ情報をインポートするには、ng-messages-include属性を利用します(リスト2)。

HTML
<label for="age">年齢:</label><br />
<input id="age" name="age" type="number" ng-model="user.age"
  required min="20" max="60" />
<span ng-messages="myForm.age.$error" ng-messages-multiple>
  <span ng-messages-include="messages_template.html"></span>
</span>
リスト2 別ファイルのメッセージ情報をインクルードするコード(messages_include.html)

 また、リスト3の1のように別ファイルで定義されたメッセージを、ng-message属性で上書きすることも可能です。

HTML
<label for="age">年齢:</label><br />
<input id="age" name="age" type="number" ng-model="user.age"
  required min="20" max="60" />
<span ng-messages="myForm.age.$error" ng-messages-multiple>
  <!--1メッセージを上書き-->
  <span ng-message="min, max">
    入力値は20~60の範囲で入力してください。</span>
  <span ng-messages-include="messages_template.html"></span>
</span>
リスト3 インクルードした別ファイルのメッセージ情報を、元のファイル側で上書きするコード(messages_include.html)

 ちなみに、ng-messages-include属性は、AngularJS 1.3では(配下の要素ではなく)ng-messages属性と同じ要素で指定する仕様でした(リスト4)。1.4のままのコードでは、1.3環境では動作しませんので注意してください(逆も同様です)。

HTML
<span ng-messages="myForm.age.$error" ng-messages-multiple
  ng-messages-include="messages_template.html">
  <span ng-message="min">20以上で入力してください。</span>
  <span ng-message="max">60以内で入力してください。</span>
</span>
リスト4 上のコードをAngularJS 1.3で動作するように書き換えた場合(messages_include1_3.html)

メッセージをテンプレートとして切り出す

 切り出したメッセージを(別ファイルではなく)ページ内でテンプレートとして準備しておくこともできます。その場合は、<script>要素を利用します。

HTML
<script type="text/ng-template" id="my-error-messages">
  <span ng-message="required">入力は必須です。</span>
  <span ng-message="min, max">
    入力値が小さすぎるか、大きすぎます。</span>
  <span ng-message="number">数値で入力してください。</span>
</script>

<span ng-messages="myForm.age.$error" ng-messages-multiple>
  <span ng-message="min, max">
    入力値は20~60の範囲で入力してください。</span>
  <span ng-messages-include="my-error-messages"></span>
</span>
リスト5 同じファイル内でメッセージをテンプレート定義するコード(messages_in_template.html)

リスト3の<span ng-messages="myForm.age.$error" ng-messages-multiple>~</span>の部分をこれに書き換える。

 テンプレートであることを表すために、<script>要素にはtype="text/ng-template"属性が必須です。また、ng-messages-include属性から参照できるよう、id属性でテンプレート名を宣言しておきます。

 これで、先ほどのリスト3と同じようにng-messages-include属性からメッセージを引用できるようになります。

メッセージをJavaScript側で管理する(1.4以降)

 メッセージをJavaScriptのコードとして用意することもできます。以下のように、キーとメッセージのセットを用意してください。

JavaScript
angular.module('myApp', [ 'ngMessages' ])
  .controller('MyController', ['$scope', function($scope) {
    $scope.errors = [
      { key: 'required', msg: '入力は必須です。' },
      { key: ['min', 'max'], msg: '入力値が小さすぎるか、大きすぎます。' },
      { key: 'number', msg: '数値で入力してください。' }
    ];
  }]);
リスト6 JavaScript側でメッセージリストを準備(messages_exp.js)

 このように定義したメッセージを引用しているのが、以下のコードです。

HTML
<span ng-messages="myForm.age.$error" ng-messages-multiple>
  <span ng-repeat="error in errors">
    <span ng-message-exp="error.key">{{error.msg}}</span>
  </span>
</span>
……中略……
<script src="messages_exp.js"></script>
リスト7 JavaScriptで定義したメッセージを引用するコード(messages_exp.html)

 ng-messageng-message-exp属性は似ていますが、前者が文字列でキーを渡すのに対して、Angular式として渡せるのが後者です。ここでは「error.key」という式で、requiredminmaxなどのキーを渡しています。複数のキーを渡すならば、['min', 'max']のように配列とします。

処理対象:メッセージ管理 カテゴリ:基本
処理対象:ディレクティブ(Directive) カテゴリ:基本
API:ngMessages(ng-messages)|ngMessage(ng-message)|ngMessagesInclude(ng-messages-include)|ngMessageExp(ng-message-exp) カテゴリ:ngMessages > directive(ディレクティブ)

※以下では、本稿の前後を合わせて5回分(第14回~第18回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
14. 入力フォームに検証機能を実装するには?(form/input)

標準的な<input>要素を拡張して入力フォームに検証機能を付ける方法を説明する。

AngularJS TIPS
15. 式の真偽に応じて表示を切り替えるには?(ng-messages/ng-message)

条件式の値に応じてメッセージの表示/非表示を切り替えるために(例えばエラー時にメッセージ表示するなど)、ng-messages/ng-message属性を使用する方法を解説する。

AngularJS TIPS
16. 【現在、表示中】≫ 別ファイルやJavaScriptでメッセージを管理するには?(ng-message-include/ng-message-exp)

ng-messages属性で使用するメッセージを、ページ内でテンプレート化したり、外部ファイル化したりして効率的に管理する方法を説明する。

AngularJS TIPS
17. 入力値のモデルへの反映タイミングを変更するには?(ng-model-options)

AngularJSのデータバインディング機能により入力値がモデルに反映されるのを、指定したミリ秒数後やフォーカスが外れたときまで遅延させる方法を説明する。

AngularJS TIPS
18. 文字列を大文字/小文字に変換するには?(lowercase/uppercase)

lowercase/uppercaseフィルターを使って文字列を大文字や小文字に変換する方法を解説。また、JavaScriptコードから変換する場合に使える$filterサービスとangular.lowercase/angular.uppercaseメソッドについても紹介する。

サイトからのお知らせ

Twitterでつぶやこう!