AngularJS 1.X对转换后的数据应用过滤器

时间:2016-07-20 17:39:11

标签: javascript angularjs html5

如果我将ng-repeatfilter一起使用,则会产生相当不错的搜索功能。但是如果我转换数据,我就不能真正使用过滤器进行搜索。

Exmple

JS

$scope.ints = [0,1,2,4,5,6,7,8,9, ..., 99, 100]
$scope.query = ''

HTML

<p ng-repeat="num in ints | filter: query">
{{num}} in hex {{num.toString(16).upperCase()}}
</p>

我想通过查询搜索(过滤)普通和十六进制数字。

这只是数字的一个例子,但它也可能是日期或日期差异(比如将unix秒的日期差异转换为“4天前”)

2 个答案:

答案 0 :(得分:4)

让我们注意a filter具有以下结构:

{{ filter_expression | filter : expression : comparator : anyPropertyKey}}

比较器用于确定是否应将期望值(来自过滤器表达式)和实际值(来自阵列中的对象)视为匹配。它可以用作具有以下签名的函数:function(actual, expected)如果两个值都应该被认为是相等的,则返回true。

这允许您根据需要对其进行配置,并且可以非常轻松地向其中添加新的相等表达式。

这是一个严格要求的例子:

angular
  .module("myApp", [])
  .controller('MyCtrl', ['$scope',
    function($scope) {
      $scope.ints = (function() {
        var toReturn = [];

        for (var i = 1; i <= 1000; i++) {
          toReturn.push(i);
        }

        return toReturn;
      })();

      $scope.comparator = function(actual, expected) {
        // This way the filter will display all values if "query" is empty
        if (expected === null || expected === '') {
          return true;
        }

        return actual.toString().toUpperCase() === expected.toString().toUpperCase() || actual.toString(16).toUpperCase() === expected.toString(16).toUpperCase();
      }
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <input type="text" ng-model="query">
  <p ng-repeat="num in ints | filter: query : comparator">
    {{ num }} in hex {{ num.toString(16).toUpperCase(); }}
  </p>
</div>

这是一个宽松平等的例子:

angular
  .module("myApp", [])
  .controller('MyCtrl', ['$scope',
    function($scope) {
      $scope.ints = (function() {
        var toReturn = [];

        for (var i = 1; i <= 1000; i++) {
          toReturn.push(i);
        }

        return toReturn;
      })();

      $scope.comparator = function(actual, expected) {
        // This way the filter will display all values if "query" is empty
        if (expected === null || expected === '') {
          return true;
        }

        var actualBase10String = actual.toString().toUpperCase();
        var actualBase16String = actual.toString(16).toUpperCase();

        var expectedBase10String = expected.toString().toUpperCase();
        var expectedBase16String = expected.toString(16).toUpperCase();

        return actualBase10String.indexOf(expectedBase10String) !== -1 || actualBase16String.indexOf(expectedBase16String) !== -1;
      }
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <input type="text" ng-model="query">
  <p ng-repeat="num in ints | filter: query : comparator">
    {{ num }} in hex {{ num.toString(16).toUpperCase(); }}
  </p>
</div>

答案 1 :(得分:0)

如果在ng-repeat中你需要同时显示旧值和新值,我会在控制器中创建一个函数来进行转换,并对保留旧值和新值的对象数组进行重复:

var myApp = angular.module('myApp',[])
.controller('MyCtrl', function($scope) { 
  var original = [0,1,2,3,4]
  var strings = ['a', 'b', 'c', 'd', 'e']
  
  $scope.ints = transform(original)
  $scope.query = ''

  function transform(values) {
    var newValues = [];
    for (var i =0; i < values.length; i++) {
      newValues.push({original: values[i], transformed: strings[values[i]]})
    }
    return newValues;
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
 <input type="search" ng-model="query" />
<p ng-repeat="num in ints | filter: query">
{{num.original}} in string {{num.transformed}}
</p>
</div>

否则,如果您不需要ng-repeat中的旧值,则解决方案更简单,只需在模型上调用转换函数。

var myApp = angular.module('myApp',[])
.controller('MyCtrl', function($scope) { 
  var strings = ['a', 'b', 'c', 'd', 'e']
  $scope.ints = [0,1,2,3,4]
  $scope.query = ''

  $scope.transform = function(values) {
return values.map(v => strings[v])
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>

<div ng-app="myApp" ng-controller="MyCtrl">
<input type="search" ng-model="query" />
<p ng-repeat="num in transform(ints) | filter: query">
    {{num}}
</p>
</div>

当然,在transform()函数中,您可以进行所需的各种转换