Я использую стандартный ng-repeat, чтобы отобразить некоторую информацию.
Разметка начинается следующим образом:
<tr ng-repeat="p in currentpicks |filter:searchQuery | orderBy:['mcu','psn','litm']" bs-pop>
<td>{{$index+1}}</td>
<td>{{p.mcu}}</td>
<td>
{{p.psn}}
Мне нужно каждый раз, когда p.psn
меняет что-то с стилем строки:
Дополнительная информация: мне нужно, чтобы каждый раз, когда таблица была создана, чтобы "поймать" меняющийся p.psn и добавить стиль, чтобы определить изменение. Я просто имею данные из $ http, и мне нужно различать строки таблицы, когда зарегистрированная изменяет значение.
Как мне это сделать?
<tr ng-repeat="p in currentpicks ...." ng-class="{'special': isSpecial(p)}" ....
CSS
.special {
background-color: red;
}
скрипт
$scope.isSpecial = function(pick) {
return pick.psn > 1000; //whatever condition
};
ng-class
, class
не будет ничего делать с объектом
Я думаю, что лучше всего будет реализовать собственный фильтр, который аннотирует модель с дополнительной информацией, необходимой для пользовательского интерфейса.
Проблема с попыткой сделать что-то встроенное заключается в том, что вам нужен доступ к предыдущему элементу в списке, а фильтры, которые вы используете, не позволяют вам просто смотреть на currentpicks[$index-1]
. Фильтры могут просматривать и изменять весь список, поэтому у вас есть доступ к предыдущему элементу в этот момент.
Код для вашего фильтра будет выглядеть так:
app.filter("annotateChange", function () {
return function (list) {
var lastPsn = list[0].psn;
for (var i = 0; i < list.length; ++i) {
if (lastPsn != list[i].psn) {
list[i].changed = true;
lastPsn = list[i].psn;
}
else {
list[i].changed = false;
}
}
return list;
};
});
И ваша разметка изменится на:
<tr ng-repeat="p in currentpicks |filter:searchQuery
|orderBy:['mcu','psn','litm']
|annotateChange"
ng-class="{row-changed-class: p.changed}" bs-pop>
<td>{{$index+1}}</td>
<td>{{p.mcu}}</td>
<td>{{p.psn}}</td>
</tr>
В этом примере row-changed-class
- это класс, который присваивается строкам, где psn
изменился.
Вышеприведенный код является упрощенным примером, который имеет пару вопросов, которые вы, возможно, захотите рассмотреть, прежде чем вводить их в производство:
В настоящее время фильтр не проверяет ошибки, поэтому, если вы использовали его на чем-либо, кроме массива, он имел бы ошибки.
Фильтр изменяет исходные экземпляры модели, чтобы добавить changed
свойство. Это может быть проблемой для других пользователей модели. Чтобы этого избежать, ваш фильтр может быть изменен для возврата клонов исходных экземпляров модели, с changed
свойством, добавленным к клонам.
Свойство, которое вы используете для обнаружения изменений, в настоящее время жестко закодировано. Возможно, вы захотите изменить фильтр, чтобы передать имя свойства. Это сделает его более многоразовым и легче изменить.
<tr ng-class="{'myCssClass': addAwesomeStyle(p.psn, $index)}" ng-repeat="p in currentpicks |filter:searchQuery | orderBy:['mcu','psn','litm']" bs-pop>
<td>{{$index+1}}</td>
<td>{{p.mcu}}</td>
<td>
{{p.psn}}
и в вашем контроллере:
$scope.addAwesomeStyle = function(psn, index){
var prev = $scope.data[index - 1];
// compare stuff...
return true;
}
Это должно вас разобраться! FWIW Я, вероятно, не пойдет по этому пути, похоже, немного назад. Я бы попытался применить правила стилизации впереди. То есть, если вы не будете меняться на ходу!
если вы не хотите написать директиву, которую вы затем можете прикрепить к тегу html в своем коде, я бы предложил добавить $watchColletion
к вашему связанному контроллеру:
На сайте angularJs есть отличный пример: https://docs.angularjs.org/api/ng/type/$rootScope.Scope
Учитывая, что angularJs представляет собой двустороннюю привязку данных - изменения, которые вы делаете в своей коллекции currentpicks
должны автоматически отражаться в вашем представлении. Если они этого не делают, вы всегда можете вызвать $scope.$apply();
Если вы хотите выполнить метод при изменении значения, вы всегда можете реализовать что-то вроде этого:
function myCtrl($scope) {
$scope.clicks = [];
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;
$scope.blank = "Hello World";
$scope.$watchCollection('names', function(newNames, oldNames) {
if (newNames !== oldNames) {
$scope.clicks.push(oldNames);
$scope.dataCount = newNames.length;
}
});
$scope.doSomething = function(){
$scope.names.pop();
$scope.$digest();
}
}
Таким образом, вы можете получить право в середине процесса и выполнить любой пользовательский код, который вы хотите.
Скрипач здесь: https://jsfiddle.net/20p96wv7/
ng-class
и пусть процесс дайджеста позаботится об этом за вас!