2017-01-24 5 views
1

複数のプロパティで結果をフィルタリングしたいと思います。 マイコード:AngularJSプロパティの配列による項目のフィルタリング(チェックボックス)

(function() { 
 
    'use strict'; 
 
    angular. 
 
    module('myApp', []). 
 
    filter('byFeatures', byFeatures). 
 
    controller('MyCtrl', MyCtrl); 
 

 
    function byFeatures() { 
 
    return function (items, conditions) { 
 
     if (Object.getOwnPropertyNames(conditions).length === 0) { 
 
     return items; 
 
     } 
 
     var filtered = []; 
 
     for (var i = 0; i < items.length; i++) { 
 
     var item = items[i]; 
 
     angular.forEach(item.features, function (feature) { 
 
      if (conditions[feature.name] !== undefined && conditions[feature.name][feature.value] !== undefined) { 
 
      if (conditions[feature.name][feature.value]) { 
 
       //filtered.push(item); 
 
       filtered[item.id] = item; 
 
      } 
 
      } 
 
     }); 
 
     } 
 
     //console.log(filtered); 
 
     return filtered; 
 
    }; 
 
    }; 
 

 
    function MyCtrl($scope, $filter) { 
 
    $scope.allProducts = [{ 
 
     id: 0, 
 
     name: "Product A", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Apple" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 1, 
 
     name: "Product B", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Apple" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "32" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 2, 
 
     name: "Product C", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Nokia" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 3, 
 
     name: "Product A", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Samsung" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
    ]; 
 
    $scope.filters = [{ 
 
     name: "Brand", 
 
     values: [ 
 
      "Apple", 
 
      "Nokia", 
 
      "Samsung", 
 
     ] 
 
     }, 
 
     { 
 
     name: "Memory", 
 
     values: [ 
 
      "16", 
 
      "32", 
 
     ] 
 
     }, 
 
    ]; 
 
    $scope.currentFilter = {}; 
 
    $scope.$watch('currentFilter', function (newValue, oldValue, scope) { 
 
     //console.log(newValue); 
 

 
     $scope.products = $filter('byFeatures')($scope.allProducts, newValue); 
 
    }, true); 
 

 
    }; 
 
}());
<html> 
 
    <head> 
 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
 
    <meta name="robots" content="noindex, nofollow"> 
 
    <meta name="googlebot" content="noindex, nofollow"> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
 
    <title></title> 
 
</head> 
 

 
<body ng-app="myApp" class="ng-scope"> 
 
    <div ng-controller="MyCtrl" style="width: 100%;"> 
 
    
 
    <div style="width: 50%; float: left;"> 
 
     <h2>Available Phones</h2> 
 
     <div ng-repeat="product in products"> 
 
     <h3> 
 
      {{ product.name }} 
 
     </h3> 
 
     <ul> 
 
      <li ng-repeat="feature in product.features"> 
 
      {{feature.name}} : {{feature.value}} 
 
      </li> 
 
     </ul> 
 
     </div> 
 
    </div> 
 
    <div style="width: 50%; float: left;"> 
 
     <h2>Filters</h2> 
 
     <pre>{{currentFilter|json}}</pre> 
 
     <div ng-repeat="filter in filters"> 
 
     <span>{{filter.name}}</span> 
 
     <ul> 
 
      <li ng-repeat="value in filter.values"> 
 
      <input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br> 
 
      </li> 
 
     </ul> 
 
     </div> 
 
    </div> 
 
</div> 
 

 

 
</body></html>

私はブランド "アップル" でフィルタする場合は、ブランド "リンゴ"(16と32のメモリ)と2台の電話機を表示している - そのOK。しかし、私はメモリ "16"で2番目のフィルタを追加する場合 - メモリ "16"と1アップルのリンゴだけを表示する必要があります。 どうすればいいですか? 。 JSFiddle

答えて

0

問題へのリンクは、あなたが何をしたいから反対のことをやっているということです:あなたは、製品のアイテム(ブランドまたはメモリ)ののための有効なプロパティが含まれていることを確認しています。必要なのは、商品にすべてのの商品(ブランドのメモリ)の有効なプロパティがあるかどうかを確認することです。

関連するすべての条件(その値が真の場合)を見つけるために、関数内のループを変更するだけで十分であり、当社の製品がブランド、メモリごとに選択されたプロパティの1つを持つことを確認してください。ここでは、右のスニペットを見ることができます:

(function() { 
 
    'use strict'; 
 
    angular. 
 
    module('myApp', []). 
 
    filter('byFeatures', byFeatures). 
 
    controller('MyCtrl', MyCtrl); 
 

 
    function byFeatures() { 
 
    return function (items, conditions) { 
 
     if (Object.getOwnPropertyNames(conditions).length === 0) { 
 
     return items; 
 
     } 
 
     var filtered = []; 
 
     for (var i = 0; i < items.length; i++) { 
 
     var item = items[i], 
 
      hasProperties = true; 
 

 
     angular.forEach(conditions, function (value, key) { 
 
      for (var i = 0; i < item.features.length; i++) { 
 
      if (item.features[i].name === key && (!value.hasOwnProperty(item.features[i].value) || !value[item.features[i].value])) { 
 
       for (var j in value) { 
 
       if (value[j]) { 
 
        hasProperties = false; 
 
       } 
 
       } 
 
      } 
 
      } 
 
     }); 
 

 
     if (hasProperties) { 
 
      filtered.push(item); 
 
     } 
 
     } 
 
     //console.log(filtered); 
 
     return filtered; 
 
    }; 
 
    }; 
 

 
    function MyCtrl($scope, $filter) { 
 
    $scope.allProducts = [{ 
 
     id: 0, 
 
     name: "Product A", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Apple" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 1, 
 
     name: "Product B", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Apple" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "32" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 2, 
 
     name: "Product C", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Nokia" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     id: 3, 
 
     name: "Product A", 
 
     features: [{ 
 
      name: "Brand", 
 
      value: "Samsung" 
 
      }, 
 
      { 
 
      name: "Memory", 
 
      value: "16" 
 
      }, 
 
      { 
 
      name: "Color", 
 
      value: "Black" 
 
      } 
 
     ] 
 
     }, 
 
    ]; 
 
    $scope.filters = [{ 
 
     name: "Brand", 
 
     values: [ 
 
      "Apple", 
 
      "Nokia", 
 
      "Samsung", 
 
     ] 
 
     }, 
 
     { 
 
     name: "Memory", 
 
     values: [ 
 
      "16", 
 
      "32", 
 
     ] 
 
     }, 
 
    ]; 
 
    $scope.currentFilter = {}; //$scope.filters; 
 
    $scope.$watch('currentFilter', function (newValue, oldValue, scope) { 
 
     $scope.products = $filter('byFeatures')($scope.allProducts, newValue); 
 
    }, true); 
 

 
    }; 
 
}());
<html> 
 

 
<head> 
 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
 
    <meta name="robots" content="noindex, nofollow"> 
 
    <meta name="googlebot" content="noindex, nofollow"> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
 
    <script src="js/script.js"></script> 
 
    <title></title> 
 
</head> 
 

 
<body ng-app="myApp" class="ng-scope"> 
 
    <div ng-controller="MyCtrl" style="width: 100%;"> 
 
    <div style="width: 50%; float: left;"> 
 
     <h2>Available Phones</h2> 
 
     <div ng-repeat="product in products"> 
 
     <h3> 
 
      {{ product.name }} 
 
     </h3> 
 
     <ul> 
 
      <li ng-repeat="feature in product.features"> 
 
      {{feature.name}} : {{feature.value}} 
 
      </li> 
 
     </ul> 
 
     </div> 
 
    </div> 
 
    <div style="width: 50%; float: left;"> 
 
     <h2>Filters</h2> 
 
     <pre>{{currentFilter|json}}</pre> 
 
     <div ng-repeat="filter in filters"> 
 
     <span>{{filter.name}}</span> 
 
     <ul> 
 
      <li ng-repeat="value in filter.values"> 
 
      <input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br> 
 
      </li> 
 
     </ul> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body> 
 

 
</html>

私はまた、あなたがフィルター配列に新製品を追加した方法を変更しました。それ以外の場合、唯一の項目のIDが2の場合、配列は最初の2つの位置を「未定義」とし、ngRepeatの繰り返しによって問題を引き起こします

関連する問題