Как назначить класс для отчета не для нечетных, четных строк, а при изменении столбца даты?
У меня очень простой отчет в AngularJS:
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody"
<div class="gridRow" ng-repeat="row in rps.reports">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
Отчет работает, но при изменении даты его трудно заметить.
Есть ли способ, которым я мог бы назначить класс для строки сетки, чтобы одна строка сетки дат имела один класс, а следующая дата, когда в строке решетки есть другой класс. Я думаю, что это уже доступно для нечетных и четных строк с Angular, но здесь мне нужно, чтобы он работал при каждом изменении даты.
Ответы
Ответ 1
Я создал очень простое и рабочее решение для этого, используя angular-filter
, вам нужно добавить динамический класс на gridRow
.
jsfiddle
HTML
<div ng-repeat="row in rps.reports"
class="gridRow {{row.date | filterDate}}">
Стили
.even {
background-color: green;
color: #fff;
}
.odd {
background-color: red;
color: #000;
}
Angular -filter
myApp.filter('filterDate', function() {
var lastDate,
count = 0,
calssName = 'even';
return function(date) {
var newDate = new Date(date).toDateString();
!lastDate && (lastDate = newDate);
if (newDate != lastDate) {
if (calssName == 'even') {
calssName = 'odd';
} else {
calssName = 'even';
}
}
lastDate = newDate;
return calssName;
}
});
Ответ 2
Я сделал другое решение (PLUNKER), где вся работа находится внутри контроллера. Может быть, это немного больше кода, но вы получите большую производительность, если у вас есть тысячи записей, потому что вы избежите грязной проверки ng-class
.
Кроме того, если ваш отчет статичен и он не будет иметь никаких изменений, вы можете отключить привязку данных...
CONTROLLER
vm.reports = addReportCssClases();
function addReportCssClases() {
var reportsData = [...];
var classes = ['dateOdd', 'dateEven'];
var index = 0;
reportsData[0].cssClass = classes[index];
for (var i = 1; i < reportsData.length; i++) {
var row = reportsData[i];
index = (row.date !== reportsData[i-1].date) ? (1 - index) : index;
row.cssClass = classes[index] ;
}
return reportsData;
}
HTML
<div ng-repeat="row in vm.reports track by $index" class="gridRow {{::row.cssClass}}">
<div>{{::row.user}}</div>
<div>{{::row.date}}</div>
<div>{{::row.count}}</div>
</div>
Ответ 3
Вы можете использовать ng-class
с функцией, определенной в вашем контроллере. Например:
var currentColor = "color1";
$scope.getClass = function(index)
{
if (index !== 0 && $scope.data[index].date !== $scope.data[index - 1].date)
{
currentColor = currentColor == "color1" ? "color2" : "color1";
}
return currentColor;
}
И в вашем шаблоне:
<div class="gridRow" ng-repeat="(i, d) in data" data-ng-class="getClass(i)">
Смотрите плункер: http://plnkr.co/edit/PPPJRJJ1jHuJOgwf9lNK
Ответ 4
Это можно сделать с помощью одной строки, учитывая, что все даты на самом деле совпадают с тем же форматом, а не с датой даты
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div ng-repeat="row in rps.reports" class="gridRow" ng-class="{'backblue':$index>0 && row.date!=rps.reports[$index-1].date}">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
ваш класс gridRow должен содержать фоновый цвет
.gridRow{
//other styles
background-color:red;
}
а класс backblue должен иметь только фоновый цвет
.backblue{
background-color:blue !important;
}
ВАЖНО
Это будет работать, только если поле даты является только датой и не имеет времени. Если в любом случае у вас есть время, вам придется конвертировать каждое время и дату
Ответ 5
Измененная версия ответа @ssougnez, сохраняя текущую дату также в дополнение к цвету:
if(!(currentDate && currentDate === data.date)){
currentColor = currentColor == "color1" ? "color2" : "color1";
currentDate = data.date;
}
Plunker: http://plnkr.co/edit/o3YVBB
Это может иметь меньшее влияние на производительность, чем его версия.
Ответ 6
var app = angular.module('sample', []);
app.controller('SampleController', function($scope)
{
$scope.data = [
{
user: "A",
date: "3/2/2017"
},
{
user: "B",
date: "3/4/2017"
},
{
user: "C",
date: "4/3/2017"
},
{
user: "D",
date: "4/3/2017"
},
{
user: "E",
date: "4/3/2017"
},
{
user: "F",
date: "4/2/2017"
}
];
});
.same{
background-color:#ddd;
}
.differ{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html ng-app="sample">
<head>
</head>
<body>
<div ng-controller="SampleController">
<table id="myTable">
<thead>
<tr>
<th>User</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td>{{row.user}}</td>
<td class="same" ng-if="data[$index+1].date==row.date || data[$index-1].date==row.date">{{row.date}}</td>
<td class="differ" ng-if="data[$index+1].date!=row.date && data[$index-1].date!=row.date">{{row.date}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Ответ 7
Вы можете добавить класс с выражением, используя директиву ngClass
в представлении:
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
var date = new Date();
$scope.rps = {
reports: [{
user: 'User A',
date: date.setDate(date.getDate() + 1),
count: 5
},
{
user: 'User B',
date: date.setDate(date.getDate() + 2),
count: 10
},
{
user: 'User C',
date: date.setDate(date.getDate()),
count: 8
},
{
user: 'User D',
date: date.setDate(date.getDate() + 2),
count: 6
},
{
user: 'User E',
date: date.setDate(date.getDate()),
count: 20
},
{
user: 'User F',
date: date.setDate(date.getDate() + 3),
count: 6
}
]
};
}
})();
.gridHeader,
.gridRow {
display: table-row;
}
.gridHeader>div,
.gridRow>div {
display: table-cell;
padding: 5px 10px;
}
.className {
background: #ff0000;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as MainCtrl">
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div class="gridRow" ng-repeat="row in ::rps.reports track by $index" ng-class="::{'className': $index === 0 || $index > 0 && rps.reports[$index - 1].date !== row.date}">
<div>{{::row.user}}</div>
<div>{{::row.date | date: 'dd-MM-yyyy'}}</div>
<div>{{::row.count}}</div>
</div>
</div>
</div>