简体   繁体   English

角度:将函数用作自定义过滤器

[英]Angular: Using a function as a custom filter

I am trying to filter ng-repeat, but am trying to use a function rather than an actual filter to filter the data. 我正在尝试过滤ng-repeat,但是正在尝试使用函数而不是实际的过滤器来过滤数据。 I was under the impression that something like this would work 我的印象是这样的事情会起作用

<tr ng-repeat="(key, value) in dataObj| filter:dataFilter">

And define dataFilter as a scope function. 并将dataFilter定义为作用域函数。

    $scope.dataFilter = function (item) {
        console.log(item);
        return false
    };

Obviously the filter is just a test, which I would have expected to log the items and also return false for everything (thus displaying nothing after the filter is done). 显然,筛选器只是一个测试,我希望可以记录这些项目,并且对所有内容都返回false(因此在筛选器完成后不显示任何内容)。 However the filter doesn't seem to even be called because the log doesn't fire. 但是,过滤器似乎甚至没有被调用,因为日志不会触发。 I am unsure of what I am doing wrong. 我不确定自己在做什么错。 I want to try this method of using a function rather than an actual filter which needs to be injected. 我想尝试这种使用函数而不是需要注入的实际过滤器的方法。


Update with more code 更新更多代码

Directive 指示

(function () {
'use strict';
angular
    .module('test')
    .directive('myDirective', MyDirective);

function MyDirective() {
    return {
        templateUrl: 'test.html',
        controllerAs: 'controller',
        controller: 'MyController',
        "scope":{
            "dataObj" : '='
        }
    };
}
})();

Controller 调节器

(function () {
'use strict';
angular
    .module('test')
    .controller('MyController', MyController);

MyController.$inject = ['$scope'];

function MyController($scope) {

    $scope.dataFilter = function (item) {
        console.log(item);
        return false
    };

}
})();

test.html 的test.html

    <table>
        <tr ng-repeat="(key, value) in dataObj | filter:dataFilter">
            <td>{{key}}</td>
            <td>{{(value}}</td>
        </tr>
    </table>

The above code does not call the dataFilter function at all. 上面的代码根本没有调用dataFilter函数。 It appears that I have to call it as a function and possibly send it a parameter. 看来我必须将其作为函数来调用,并可能向其发送参数。 For example if I do: 例如,如果我这样做:

<tr ng-repeat="(key, value) in dataObj | filter:dataFilter()">

The console will log "undefined" a number of times equal to the number of items in dataObj. 控制台将多次记录“未定义”,该次数等于dataObj中的项目数。 (obvious since there was no parameter passed in). (很明显,因为没有传入任何参数)。 But what is perplexing is that even though I didn't pass any data in or do any real filtering, i would still expect that the view should not print out any data at all because the dataFilter() is returning false (as a test of course). 但是令人困惑的是,即使我没有传递任何数据或进行任何真正的过滤,我仍然希望该视图根本不打印任何数据,因为dataFilter()返回的是false(作为对课程)。 Yet all the data is printed out in . 然而,所有数据都已打印到中。

Overall issue 总体问题

The function as a filter doesn't seem to work at all, even when actually called. 即使实际上被调用,作为过滤器的功能也似乎根本不起作用。 I expected that a function that returns false should mean that the ng-repeat will "filter" (skip) that particular item. 我期望返回false的函数应该意味着ng-repeat将“过滤”(跳过)该特定项目。

The second issue is how to actually send the current "item" to the dataFilter function. 第二个问题是如何实际将当前的“项目”发送到dataFilter函数。 I have tried sending key and value, but neither of them are defined. 我尝试发送键和值,但是都没有定义。

It's not possible to use the standard $filter service on an object, it must be an array - the documentation is quite clear. 无法在对象上使用标准的$ filter服务,它必须是数组- 文档非常清楚。 I am unsure why you are not getting an error like this - note the link gives an example of how to implement a custom filter than operates on an object, which is what you want. 我不确定为什么你没有得到这样的错误这样 -注意链接中给出了如何不是一个对象,这是你想要的东西上操作实现自定义过滤器的例子。

Use ng-if, ng-switch etc. to control ng-repeat flow. 使用ng-if,ng-switch等控制ng-repeat流量。 Your assumption regarding $filter results affecting ng-repeat iteration is misplaced. 关于$ filter结果影响ng-repeat迭代的假设被放错了位置。

Regardless of what some might say, it's totally OK to filter an object (as opposed to an array) but as noted above that requires a custom filter, which you state you don't want, so you're left with no solution given your requirements. 无论有人怎么说,过滤一个对象(相对于数组)都是完全可以的,但是如上所述,这需要一个自定义的过滤器,您声明了自己不想要的过滤器,因此您没有解决方案要求。

Here's a fiddle that is as good as it gets without a custom filter. 这是一个无须定制过滤器的小提琴 You have to supply an array. 必须提供一个数组。

<div ng-controller="myController">
  <table>
    <tr ng-repeat="(item,result) in model | filter:myfilter"   
        ng-if="result">    
      <td>{{result.key}}=</td>
      <td>{{result.value}}</td>
    </tr>
  </table>
</div>

Note above for clarity it's (item,result) not (key,value). 请注意,为清楚起见,它不是(项,结果),不是(键,值)。 Here's the code. 这是代码。

var myApp = angular.module('myApp', []);

myApp.controller('myController', ['$scope', function($scope) {
  // You cannot pass standard $filter an object.  It MUST be an array.
  var obj = {
    pi: 3.14,
    aqua: "teen",
    then: new Date(),
    hunger: "force",
  }
  $scope.model = [];

  for (var key in obj) {
    if (obj.hasOwnProperty(key))
      $scope.model.push({
        key: key,
        value: obj[key]
      })
  }

  $scope.myfilter = function(item, index) {
    console.log(item.key + " = " + item.value)
    if (index % 2 == 0)
      return undefined;
    return item;
  }
}]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM