angular.jsをやってみる (4) - filter -

2014-03-10T00:00:00+00:00 angular.js JavaScript

angular.jsとかで

<div ng-repeat="sample in samples | filter:searchText">
  {% raw %}{{sample}}{% endraw %}
</div>

的にパイプでフィルターを指定したり出来る訳だけど、それを実装する方法

index.html

<html ng-app="sampleApp">
  <head>
    <script src="angular.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
    <div ng-controller="SampleController">
      <!-- 2で割り切れるのだけにフィルター -->
      <div ng-repeat="sample in samples | divide2">
        <!-- 自乗して出力 -->
        {% raw %}{{sample | pow2 }}{% endraw %}
      </div>
    </div>
    <script src="app.js"></script>
  </body>
</html>

app.js

angular.module("sampleApp", [], function($filterProvider) {
  /* $filterProviderを使っても出来る模様
  $filterProvider.register("divide2", function() {
    return function(values) {
    };
  });
  */
})
.controller("SampleController", function($scope) {
  $scope.samples = [1, 2, 3, 4, 5];
})
.filter("divide2", function() {
  return function(values) {
    if ("filterValues" in this)
      return this.filterValues;

    var newValues = [];
    angular.forEach(values, function(value, index) {
      if (value % 2 == 0)
        newValues.push(value);
    });

    this.filterValues = newValues;
    return newValues;
  }
})
.filter("pow2", function() {
  return function(value) {
    return Math.pow(value, 2);
  };
});

ってな感じでやると、スコープに突っ込んでるデータの内で2で割り切れる値がフィルターされて、その値が自乗フィルターされて出力される

ちなみにthis.filterValuesってな感じで突っ込んでる理由として、なぜかフィルターが2回実行される。その理由が http://qiita.com/zoetro/items/5156aef51222e81dd022 に書いているけど「値が変化した時には比較用とレンダリング用の2回フィルタが呼ばれます。」っていう事らしい

angular.jsをやってみる (5) - provider - mocha-phantomjsでlocalToRemoteUrlAccessEnabled