在div中使用ng-repeat可调整外部div的位置

时间:2015-07-23 17:52:27

标签: html css angularjs alignment

我正在使用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,因此根据卡片的对齐方式不一致: attrs alignment issue

处理此问题的有效方法是什么?

3 个答案:

答案 0 :(得分:2)

vertical-align: top;添加到您的.card_background选择器。

JSFiddle

&#13;
&#13;
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;
&#13;
&#13;

答案 1 :(得分:1)

我没有在.card_background中使用display:inline-block,而是使用float left。 试试这段代码:

&#13;
&#13;
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;
&#13;
&#13;

答案 2 :(得分:1)

这是CSS问题。只需将规则vertical-align: top添加到.card_background

即可

工作演示:http://jsfiddle.net/y49qe8o1/2/