我正在使用AngularJS v1.4.3。 Here is a fiddle of my code so far
我正在制作一个带有JSON数据的简单过滤系统,其输出会根据用户选择的类别而变化。
我使用ng-repeat
在JSON对象中显示数组的元素。每个对象都有一个attrs
数组属性。但是,有些attrs
数组有两个元素,有些有三个。
以下是HTML代码的相关部分:
<div class="cards">
<div ng-repeat="card in cards | filter:itemFilter" class="card_background">
<div class="card_title">{{card.name | uppercase}}</div>
<div class="card_properties">
<div ng-repeat="attr in card.attrs">{{attr}}</div>
</div>
</div>
</div>
以下是相关的CSS类:
.cards {
display: inline-block;
}
.card_background {
border-radius: 5px;
border: 2px solid black;
width: 130px;
height: 150px;
background-color: #DBC282;
margin: 20px;
padding: 20px;
display: inline-block;
color: black;
}
.card_title {
letter-spacing: -1px;
font-size: 140%;
text-align: center;
}
.card_properties {
text-transform: capitalize;
}
以下是一些示例JSON数据:
$scope.cards = [
{ name: 'Sniper', attrs: ['shooting', 'dribbling'] },
{ name: 'Finisher', attrs: ['shooting', 'physical'] },
{ name: 'Deadeye', attrs: ['shooting', 'passing'] },
{ name: 'Marksman', attrs: ['shooting', 'dribbling', 'physical'] },
{ name: 'Hawk', attrs: ['pace', 'shooting', 'physical'] },
...
如您所见,行<div ng-repeat="attr in card.attrs">{{attr}}</div>
是列出attrs
的行。并且因为它在某些情况下会产生两个div,而在其他情况下会产生三个div,因此根据卡片的对齐方式不一致:
处理此问题的有效方法是什么?
答案 0 :(得分:2)
将vertical-align: top;
添加到您的.card_background
选择器。
angular.module('chemistry', [])
.controller('MainCtrl', function ($scope, $http) {
// was trying to get json from separate file
// $http.get('cards.json')
// .then(function(result){
// $scope.cards2 = result.data;
// });
//18 total
$scope.cards = [{
name: 'Sniper',
attrs: ['shooting', 'dribbling']
}, {
name: 'Finisher',
attrs: ['shooting', 'physical']
}, {
name: 'Deadeye',
attrs: ['shooting', 'passing']
}, {
name: 'Marksman',
attrs: ['shooting', 'dribbling', 'physical']
}, {
name: 'Hawk',
attrs: ['pace', 'shooting', 'physical']
}, {
name: 'Artist',
attrs: ['passing', 'dribbling']
}, {
name: 'Architect',
attrs: ['passing', 'physical']
}, {
name: 'Powerhouse',
attrs: ['passing', 'defending']
}, {
name: 'Maestro',
attrs: ['shooting', 'passing', 'dribbling']
}, {
name: 'Engine',
attrs: ['pace', 'passing', 'dribbling']
}, {
name: 'Sentinel',
attrs: ['defending', 'physical']
}, {
name: 'Guardian',
attrs: ['dribbling', 'defending']
}, {
name: 'Gladiator',
attrs: ['shooting', 'defending']
}, {
name: 'Backbone',
attrs: ['passing', 'defending', 'physical']
}, {
name: 'Anchor',
attrs: ['pace', 'defending', 'physical']
}, {
name: 'Hunter',
attrs: ['pace', 'shooting']
}, {
name: 'Catalyst',
attrs: ['pace', 'passing']
}, {
name: 'Shadow',
attrs: ['pace', 'defending']
}];
$scope.options = [{
name: 'pace',
selected: false
}, {
name: 'shooting',
selected: false
}, {
name: 'passing',
selected: false
}, {
name: 'dribbling',
selected: false
}, {
name: 'defending',
selected: false
}, {
name: 'physical',
selected: false
}];
$scope.itemFilter = function (item) {
var filters = $scope.options.filter(function (element, idx, array) {
return element.selected;
}) || [];
var matched = true;
filters.forEach(function (option) {
matched = matched && item.attrs.indexOf(option.name) >= 0;
})
return matched;
};
});
&#13;
@import url(http://fonts.googleapis.com/css?family=Exo:200);
@import url(http://fonts.googleapis.com/css?family=Exo:500);
@import url(http://fonts.googleapis.com/css?family=Exo:300);
@import url(http://fonts.googleapis.com/css?family=Exo:700);
body {
background-image: url('fifa_background_image.jpg');
background-color: black;
background-attachment: fixed;
color: white;
font-family:'Exo', sans-serif;
font-weight: 200;
}
.main_title {
margin: auto;
width: 50%;
padding: 10px;
/*TEXT SETTINGS*/
letter-spacing: -1px;
color: #ffcc00;
text-align: center;
font-family:'Exo', sans-serif;
font-weight: 500;
font-size: 300%;
}
.subtitle {
color: #dcdcdc;
text-align:center;
}
.options_container {
margin: auto;
padding: 5px;
}
.option {
display: inline-block;
/*TEXT SETTINGS*/
color: #dcdcdc;
/*light grey*/
font-weight: 300;
font-size: 200%;
padding: 10px;
/*Prevent div being highlighted upon click*/
-webkit-user-select: none;
}
.option:hover {
-webkit-transition: 0.3s;
color: white;
}
/*Colour the category text*/
:checked + span {
-webkit-transition: 0.1s;
color: #ffcc00;
text-shadow: 0px 0px 30px gray;
}
.check {
/*This element is hidden */
width: 0%;
visibility: hidden;
}
.cards {
display: inline-block;
}
.card_background {
border-radius: 5px;
border: 2px solid black;
width: 130px;
height: 150px;
background-color: #DBC282;
margin: 20px;
padding: 20px;
display: inline-block;
/*TEXT SETTINGS*/
color: black;
vertical-align: top;
}
.card_title {
letter-spacing: -1px;
font-size: 140%;
text-align: center;
}
.card_properties {
text-transform: capitalize;
}
&#13;
<title>Chemistry Cards</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<body ng-controller="MainCtrl" ng-app="chemistry">
<div class="main_title">CHEMISTRY STYLES FINDER</div>
<div class="subtitle">Select categories to filter cards</div>
<div class="options_container">
<label ng-repeat="option in options" class="option">
<input type="checkbox" class="check" ng-model="option.selected" /> <span>{{option.name | uppercase}}</span>
</label>
</div>
<div class="cards">
<div ng-repeat="card in cards | filter:itemFilter" class="card_background">
<div class="card_title">{{card.name | uppercase}}</div>
<div class="card_properties">
<div ng-repeat="attr in card.attrs">{{attr}}</div>
</div>
</div>
</div>
<script src="ang.js"></script>
<script src="animations.js"></script>
</body>
</html>
&#13;
答案 1 :(得分:1)
我没有在.card_background中使用display:inline-block,而是使用float left。 试试这段代码:
angular.module('chemistry', [])
.controller('MainCtrl', function ($scope, $http) {
// was trying to get json from separate file
// $http.get('cards.json')
// .then(function(result){
// $scope.cards2 = result.data;
// });
//18 total
$scope.cards = [{
name: 'Sniper',
attrs: ['shooting', 'dribbling']
}, {
name: 'Finisher',
attrs: ['shooting', 'physical']
}, {
name: 'Deadeye',
attrs: ['shooting', 'passing']
}, {
name: 'Marksman',
attrs: ['shooting', 'dribbling', 'physical']
}, {
name: 'Hawk',
attrs: ['pace', 'shooting', 'physical']
}, {
name: 'Artist',
attrs: ['passing', 'dribbling']
}, {
name: 'Architect',
attrs: ['passing', 'physical']
}, {
name: 'Powerhouse',
attrs: ['passing', 'defending']
}, {
name: 'Maestro',
attrs: ['shooting', 'passing', 'dribbling']
}, {
name: 'Engine',
attrs: ['pace', 'passing', 'dribbling']
}, {
name: 'Sentinel',
attrs: ['defending', 'physical']
}, {
name: 'Guardian',
attrs: ['dribbling', 'defending']
}, {
name: 'Gladiator',
attrs: ['shooting', 'defending']
}, {
name: 'Backbone',
attrs: ['passing', 'defending', 'physical']
}, {
name: 'Anchor',
attrs: ['pace', 'defending', 'physical']
}, {
name: 'Hunter',
attrs: ['pace', 'shooting']
}, {
name: 'Catalyst',
attrs: ['pace', 'passing']
}, {
name: 'Shadow',
attrs: ['pace', 'defending']
}];
$scope.options = [{
name: 'pace',
selected: false
}, {
name: 'shooting',
selected: false
}, {
name: 'passing',
selected: false
}, {
name: 'dribbling',
selected: false
}, {
name: 'defending',
selected: false
}, {
name: 'physical',
selected: false
}];
$scope.itemFilter = function (item) {
var filters = $scope.options.filter(function (element, idx, array) {
return element.selected;
}) || [];
var matched = true;
filters.forEach(function (option) {
matched = matched && item.attrs.indexOf(option.name) >= 0;
})
return matched;
};
});
&#13;
@import url(http://fonts.googleapis.com/css?family=Exo:200);
@import url(http://fonts.googleapis.com/css?family=Exo:500);
@import url(http://fonts.googleapis.com/css?family=Exo:300);
@import url(http://fonts.googleapis.com/css?family=Exo:700);
body {
background-image: url('fifa_background_image.jpg');
background-color: black;
background-attachment: fixed;
color: white;
font-family:'Exo', sans-serif;
font-weight: 200;
}
.main_title {
margin: auto;
width: 50%;
padding: 10px;
/*TEXT SETTINGS*/
letter-spacing: -1px;
color: #ffcc00;
text-align: center;
font-family:'Exo', sans-serif;
font-weight: 500;
font-size: 300%;
}
.subtitle {
color: #dcdcdc;
text-align:center;
}
.options_container {
margin: auto;
padding: 5px;
}
.option {
display: inline-block;
/*TEXT SETTINGS*/
color: #dcdcdc;
/*light grey*/
font-weight: 300;
font-size: 200%;
padding: 10px;
/*Prevent div being highlighted upon click*/
-webkit-user-select: none;
}
.option:hover {
-webkit-transition: 0.3s;
color: white;
}
/*Colour the category text*/
:checked + span {
-webkit-transition: 0.1s;
color: #ffcc00;
text-shadow: 0px 0px 30px gray;
}
.check {
/*This element is hidden */
width: 0%;
visibility: hidden;
}
.cards {
display: inline-block;
}
.card_background {
border-radius: 5px;
border: 2px solid black;
width: 130px;
height: 150px;
background-color: #DBC282;
margin: 20px;
padding: 20px;
/* display: inline-block; */
float:left;
/*TEXT SETTINGS*/
color: black;
}
.card_title {
letter-spacing: -1px;
font-size: 140%;
text-align: center;
}
.card_properties {
text-transform: capitalize;
}
&#13;
<title>Chemistry Cards</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<body ng-controller="MainCtrl" ng-app="chemistry">
<div class="main_title">CHEMISTRY STYLES FINDER</div>
<div class="subtitle">Select categories to filter cards</div>
<div class="options_container">
<label ng-repeat="option in options" class="option">
<input type="checkbox" class="check" ng-model="option.selected" /> <span>{{option.name | uppercase}}</span>
</label>
</div>
<div class="cards">
<div ng-repeat="card in cards | filter:itemFilter" class="card_background">
<div class="card_title">{{card.name | uppercase}}</div>
<div class="card_properties">
<div ng-repeat="attr in card.attrs">{{attr}}</div>
</div>
</div>
</div>
<script src="ang.js"></script>
<script src="animations.js"></script>
</body>
</html>
&#13;
答案 2 :(得分:1)
这是CSS问题。只需将规则vertical-align: top
添加到.card_background