【问题标题】:How to disable an AngularJs filter when checkboxes are false (disabled)?当复选框为假(禁用)时如何禁用AngularJs过滤器?
【发布时间】:2014-08-03 04:24:19
【问题描述】:

我有一个关于如何禁用与复选框相关的 AngularJS 过滤器的问题。

我有一个经典的结构:

对象:

 $scope.wines = [
    { "name": "Wine a", "type": "red", "country": "france", "style": "strong" },
    { "name": "Wine a", "type": "white", "country": "italie", "style": "medium" },
    { "name": "Wine a", "type": "white", "country": "france", "style": "light" },
    { "name": "Wine a", "type": "rose", "country": "usa", "style": "strong" },
    { "name": "Wine a", "type": "champagne", "country": "chili", "style": "medium" },
    { "name": "Wine a", "type": "red", "country": "brazil", "style": "strong" },
    { "name": "Wine a", "type": "red", "country": "france", "style": "strong" }
  ];
  $scope.winetypes = {red : true,white : true,rose : true, champagne : true};

此过滤器用于仅显示使用复选框做出的相关选择:

app.filter('winetypefilter', function () {
  return function(input, filter) {
    var result = [];
    angular.forEach(input, function (wine) {
        angular.forEach(filter, function (isfiltered, type) {
            if (isfiltered && type === wine.type) {
                result.push(wine);
            }
        });
    });
    return result;
  };

结果用这个 html 代码显示:

<li ng-repeat="(type, value) in winetypes">
  <input type="checkbox" ng-model="winetypes[type]" /> {{type}}
</li>

<ul>
  <li ng-repeat="wine in wines | winetypefilter:winetypes">
    {{wine.name}} is a {{wine.type}} with {{wine.style}} style from {{wine.country}}
  </li>
</ul>
  • 当所有葡萄酒复选框都未选中 (false) 时,我会禁用 winetypefilter,以在页面上显示所有结果。我试过没有成功!!

这里是演示:http://plnkr.co/edit/nIQ2lkiJJY9MwJKHrqOk?p=preview

【问题讨论】:

  • 基本上你希望在所有复选框都未选中时显示所有项目?
  • 是的,没错!!很好的帮助,非常感谢!

标签: angularjs checkbox filter angularjs-ng-repeat


【解决方案1】:

您实际上可以调整您的自定义过滤器winetypefilter,以检查是否所有winetypes 布尔值都被禁用。如果所有值都被禁用,则只需返回原始数组,在本例中为 input,否则继续使用原始过滤器。

注意:我还更改了过滤 winetypes 的方式,forEach 的额外层对于确定是否应该进行过滤不是必需的。只需检查wine.type 的过滤器在winetypes json 中是否为真

Forked Plunker

例如

app.filter('winetypefilter', function () {
  return function(input, filter) {
    var result;

    if(canFilter(filter)) {
      result = [];
      angular.forEach(input, function(wine) {
        if(filter[wine.type])
          result.push(wine);
      });
    } else
      result = input;

    return result;
  };

  function canFilter(filter) {
    var hasFilter = false;
    angular.forEach(filter, function(isFiltered) {
      hasFilter = hasFilter || isFiltered;
    });
    return hasFilter;
  }
});

【讨论】:

【解决方案2】:

我用ng-if来显示是否所有的复选框都被选中...

    <ul>
      <li ng-if="check()" ng-repeat="wine in wines | winetypefilter:winetypes">
        {{wine.name}} is a {{wine.type}} with {{wine.style}} style from {{wine.country}}
      </li>
      <li ng-if="!check()" ng-repeat="wine in wines ">
        {{wine.name}} is a {{wine.type}} with {{wine.style}} style from {{wine.country}}
      </li>
    </ul>

和控制器代码..

  $scope.check=function()
  {
    if($scope.winetypes.red===false&&$scope.winetypes.white===false&&$scope.winetypes.rose===false&&$scope.winetypes.champagne===false)
    {
      return false;
    }
    return true;
  };

http://plnkr.co/edit/MWL727Yfq8MLWodmaBDk?p=preview

【讨论】:

  • 非常感谢您的帮助....我是 AngularJS 的新手,很好,因为这里有很多解决方案...谢谢!!
【解决方案3】:

http://plnkr.co/edit/w4aCjOW5UnnFQcAKYBT9?p=preview

app.filter('winetypefilter', function () {
  return function(input, filter) {
    var result = [];
    var alt = [];
    var flag = false;
    angular.forEach(input, function (wine) {
        flag = false;
        angular.forEach(filter, function (isfiltered, type) {
            if (isfiltered && type === wine.type) {
                result.push(wine);
                flag = true;
            }
        });
        if(!flag)
          alt.push(wine);
    });
    if(!angular.equals(result.length,0))
      return result;
    else
      return alt;
  };
});

根据其他 cmets 之一,您可以放弃额外的 forEach 更新 Plunker:http://plnkr.co/edit/w4aCjOW5UnnFQcAKYBT9?p=preview

app.filter('winetypefilter', function () {
  return function(input, filter) {
    var result = [];
    var alt = [];
    angular.forEach(input, function (wine) {
        if(filter[wine.type])
          result.push(wine);
        else
          alt.push(wine);
    });
    if(!angular.equals(result.length,0))
      return result;
    else
      return alt;
  };
});

【讨论】:

  • 非常感谢您的帮助....我是 AngularJS 的新手,您的代码对我帮助很大!我会冷静地分析它!问候
  • 后一个代码示例将代码减少到一个forEach,没有像@ryeballar 那样的额外函数调用,但代价是备用数组的额外内存。感谢@ryeballar 发现额外的forEach 是没有根据的。
  • 很好,我在考虑内存,尤其是当json文件长大并长大的时候。谢谢!!
猜你喜欢
  • 2017-05-28
  • 1970-01-01
  • 2014-07-28
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
相关资源
最近更新 更多