ほげにっき

hogedigoの日記

AngularJSチュートリアルやってメモメモ(step8 - フィルター)

このステップではカスタム表示フィルターの作り方を学ぶ。

目次


今回やるのはこちら↓
AngularJS: 9 - Filters


ワークスペースをstep9のにリセット。注:ローカルの修正は破棄される

git checkout -f step-9

ローカルサーバーをリフレッシュ(またはAngularサーバーで確認可)。

詳細ページの一つに遷移してみよう。

前回のステップの詳細ページでは端末の機能の有無をtrue/falseで表示していた。このステップの詳細ページではカスタムフィルターを用いてtrueならば「✓」、falseならば「✘」で表示している。


step8からstep9への変更を説明。diffはこちら

カスタムフィルター

phonecatFiltersモジュールを作成し、そこに作成したカスタムフィルターを登録する。


app/js/filters.js:

angular.module('phonecatFilters', []).filter('checkmark', function() {
  return function(input) {
    return input ? '\u2713' : '\u2718';
  };
});


新しいフィルターの名前は"checkmark"。入力がtrueかfalseかを判定して、ユニコードのtrue (\u2713 -> ✓) またはfalse (\u2718 -> ✘)を返す。

これでカスタムフィルターの用意は出来た。次にphonecatFiltersモジュールをアプリのメインのphonecatモジュールに依存モジュールとして登録する。


app/js/app.js:

...
angular.module('phonecat', ['phonecatFilters']).
...

テンプレート

フィルターのコードはapp/js/filters.jsに記述している為、これを使用するレイアウトテンプレートにインクルードする必要がある。

app/index.html:

...
 <script src="js/controllers.js"></script>
 <script src="js/filters.js"></script>
...


Angularテンプレートでフィルターを使う為の記述は以下の通り:

{{ expression | filter }}

端末詳細テンプレートに適用する。
app/partials/phone-detail.html:

...
    <dl>
      <dt>Infrared</dt>
      <dd>{{phone.connectivity.infrared | checkmark}}</dd>
      <dt>GPS</dt>
      <dd>{{phone.connectivity.gps | checkmark}}</dd>
    </dl>
...

テスト

他のコンポーネントと同様にフィルターもテストすべきで、テストは容易に記述することが出来る。

test/unit/filtersSpec.js:

describe('filter', function() {
 
  beforeEach(module('phonecatFilters'));
 
 
  describe('checkmark', function() {
 
    it('should convert boolean values to unicode checkmark or cross',
        inject(function(checkmarkFilter) {
      expect(checkmarkFilter(true)).toBe('\u2713');
      expect(checkmarkFilter(false)).toBe('\u2718');
    }));
  });
});

全てのテスト実行の前にphonecatFiltersモジュールをテスト用インジェクターに設定する必要があるので注意。


Karmaのテスト結果が成功していることを確認。

Chrome 22.0: Executed 4 of 4 SUCCESS (0.034 secs / 0.012 secs)

実験

  • ビルトインAngularフィルターのいくつかをindex.htmlのバインディングに適用してみよう。
    • {{ "lower cap string" | uppercase }}
    • {{ {foo: "bar", baz: 23} | json }}
    • {{ 1304375948024 | date }}
    • {{ 1304375948024 | date:"MM/dd/yyyy @ h:mma" }}
  • input要素に紐づいているモデルに対してフィルターを適用することも出来る。index.htmlに下記を追加してみよう。
<input ng-model="userInput"> Uppercased: {{ userInput | uppercase }}


今日はここまで。次回はstep10 - イベントハンドラ