我正在开发一个使用 AngularJS 过滤 JSON 数据的原型。一个工作沙箱在这里:
https://codepen.io/ixdarchitects/pen/BaypxrW
我需要你的帮助来解决 2 个问题:
- 如何使用“全选”和“取消全选”按钮来激活/停用所有复选框过滤器?
- 默认过滤:如何让网页初始化时只显示灰鸟?
谢谢

HTML:
<div ng-app="petSelector" ng-controller="PetCtrl" class="wrapper">
<h1>Pet Picker!</h1>
<hr>
<h3>Problems to solve:</h3>
<ol>
<li>How to use the "Check All" and "Uncheck All" button to activate/deactivate all of the checkbox filters?</li>
<li>Filter by default: How to make the webpage only show gray bird when the page is initialized?</li>
</ol>
<hr>
<div class="attr" ng-repeat="(prop, ignoredValue) in pets[0].FilterAttributes" ng-init="filter[prop]={}" ng-class="prop">
<b>{{prop}}:</b><br />
<span class="checkbox" ng-repeat="opt in getOptionsFor(prop)">
<label><input type="checkbox" ng-model="filter[prop][opt]" /> {{opt}}</label>
</span>
</div>
<button ng-click="checkAll()" style="margin-right: 10px">Check all</button>
<button ng-click="uncheckAll()" style="margin-right: 10px">Uncheck all</button>
<div class="results">Number of results: {{filtered.length}}</div>
<div class="pet" ng-repeat="p in filtered=(pets | filter:filterByProp | orderBy:order)">
<img ng-src="{{p.img}}">
<p>{{p.name}}</p>
</div>
<div ng-if="filtered.length == 0">Sorry, nothing matches your selection</div>
</div>
JS:
var petSelector = angular.module("petSelector", []);
petSelector.controller("PetCtrl", [
"$scope",
function($scope) {
$scope.pets = [
{
name: "Finch",
FilterAttributes: { species: "bird", size: "x-small", color: "red" },
img:
"http://upload.wikimedia.org/wikipedia/commons/7/7c/Fringilla_coelebs_chaffinch_male_edit2.jpg"
},
{
name: "Cockatiel",
FilterAttributes: { species: "bird", size: "small", color: "yellow" },
img: "http://upload.wikimedia.org/wikipedia/commons/0/07/Captive.jpg"
},
{
name: "African Gray Parrot",
FilterAttributes: { species: "bird", size: "large", color: "gray" },
img:
"http://upload.wikimedia.org/wikipedia/commons/2/28/Psittacus_erithacus_-perching_on_tray-8d.jpg"
},
{
name: "Macaw",
FilterAttributes: { species: "bird", size: "x-large", color: "blue" },
img:
"http://upload.wikimedia.org/wikipedia/commons/0/00/Macaw.blueyellow.arp.750pix.jpg"
},
{
name: "Shih Tzu",
FilterAttributes: { species: "dog", size: "x-small", color: "multi" },
img: "http://upload.wikimedia.org/wikipedia/commons/3/30/Shih-Tzu.JPG"
},
{
name: "Border Collie",
FilterAttributes: { species: "dog", size: "small", color: "multi" },
img:
"http://upload.wikimedia.org/wikipedia/commons/b/b1/Border_Collie_liver_portrait.jpg"
},
{
name: "American Staffordshire Terrier",
FilterAttributes: { species: "dog", size: "large", color: "gray" },
img: "http://upload.wikimedia.org/wikipedia/commons/d/de/AmStaff2.jpg"
},
{
name: "Bullmastiff",
FilterAttributes: { species: "dog", size: "x-large", color: "brown" },
img:
"http://upload.wikimedia.org/wikipedia/commons/9/9e/Bullmastiff_Junghund_1_Jahr.jpg"
}
];
$scope.filter = {};
$scope.getOptionsFor = function(propName) {
return ($scope.pets || [])
.map(function(p) {
return p.FilterAttributes[propName];
})
.filter(function(p, idx, arr) {
return arr.indexOf(p) === idx;
});
};
$scope.filterByProp = function(pets) {
var matchesAND = true;
for (var prop in $scope.filter) {
if (noSubFilter($scope.filter[prop])) continue;
if (!$scope.filter[prop][pets.FilterAttributes[prop]]) {
matchesAND = false;
break;
}
}
return matchesAND;
};
function noSubFilter(subFilterObj) {
for (var key in subFilterObj) {
if (subFilterObj[key]) return false;
}
return true;
}
}
]);
CSS
* {
box-sizing: border-box;
}
body {
font-family: 'Helvetica', arial, sans-sarif;
color: #fff;
}
h1 {
color: #fff;
margin: 0;
}
p {
margin-top: 0;
}
b {
color: #fff;
text-transform: uppercase;
}
.wrapper {
width: 800px;
margin: 20px auto;
padding: 40px;
background: #00a5bb;
border-radius: 8px;
}
.attr {
width: 32%;
margin: 0 .5%;
padding: 20px;
display: inline-block;
vertical-align: top;
}
.checkbox {
width: 49%;
display: inline-block;
margin: 10px 0 0;
}
.results {
font-size: 12px;
margin: 10px 0 20px;
padding-bottom: 10px;
border-bottom: 1px solid white;
}
.pet {
margin-bottom: 10px;
display: inline-block;
width: 33%;
text-align: center;
}
.pet img {
max-width: 85%;
max-height: 200px;
}
.pet.ng-enter, .pet.ng-leave {
-webkit-transition: all linear 0.5s;
transition: all linear 0.5s;
}
.pet .ng-enter {
opacity: 0;
}
.pet.ng-enter-active {
opacity: 1;
height: auto;
}
.pet.ng-leave-active {
opacity: 0;
height: 0;
}