Как обнаружить изменение значения в таблице AngularJS?

0

Я использую стандартный 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 меняет что-то с стилем строки:

Изображение 174551

Дополнительная информация: мне нужно, чтобы каждый раз, когда таблица была создана, чтобы "поймать" меняющийся p.psn и добавить стиль, чтобы определить изменение. Я просто имею данные из $ http, и мне нужно различать строки таблицы, когда зарегистрированная изменяет значение.

Как мне это сделать?

  • 1
    На большом столе это создаст много дорогих часов. Как это меняется? Кроме того, что вы пробовали?
  • 0
    См. Мой комментарий к ответу. Когда я говорю «изменить», я имею в виду, что мне нужно определиться с форматом, когда я загружаю данные в исходное состояние. Затем я ничего не меняю
Показать ещё 8 комментариев
Теги:
angularjs-ng-repeat

4 ответа

1
<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
};
  • 0
    Мне нужно проверить pick.psn с ПРЕДЫДУЩИМ значением pick.psn ...
  • 1
    менее дорогой, если не использовать функцию. Также должен быть NG ng-class , class не будет ничего делать с объектом
Показать ещё 1 комментарий
0

Я думаю, что лучше всего будет реализовать собственный фильтр, который аннотирует модель с дополнительной информацией, необходимой для пользовательского интерфейса.

Проблема с попыткой сделать что-то встроенное заключается в том, что вам нужен доступ к предыдущему элементу в списке, а фильтры, которые вы используете, не позволяют вам просто смотреть на 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 изменился.

Вышеприведенный код является упрощенным примером, который имеет пару вопросов, которые вы, возможно, захотите рассмотреть, прежде чем вводить их в производство:

  1. В настоящее время фильтр не проверяет ошибки, поэтому, если вы использовали его на чем-либо, кроме массива, он имел бы ошибки.

  2. Фильтр изменяет исходные экземпляры модели, чтобы добавить changed свойство. Это может быть проблемой для других пользователей модели. Чтобы этого избежать, ваш фильтр может быть изменен для возврата клонов исходных экземпляров модели, с changed свойством, добавленным к клонам.

  3. Свойство, которое вы используете для обнаружения изменений, в настоящее время жестко закодировано. Возможно, вы захотите изменить фильтр, чтобы передать имя свойства. Это сделает его более многоразовым и легче изменить.

0
<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 Я, вероятно, не пойдет по этому пути, похоже, немного назад. Я бы попытался применить правила стилизации впереди. То есть, если вы не будете меняться на ходу!

  • 0
    Я предпочел бы применить вещи у pfront .. Но как?
  • 0
    @ e4rthdog действительно трудно сказать, не понимая, как структурированы ваши данные и какие проверки вам необходимо выполнить. Большой проблемой является то, что метод будет вызываться для каждой строки / для дайджеста, что приведет к МНОЖЕСТВУ обращений к связанному выражению. В предыдущем постере упоминалось, что это будет дорого и так будет, особенно если ваша коллекция большая.
Показать ещё 3 комментария
0

если вы не хотите написать директиву, которую вы затем можете прикрепить к тегу 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/

  • 0
    Возможно, я ввел вас в заблуждение .. Когда я говорю изменение, я имею в виду начальную выборку данных .. Я не изменяю данные после их загрузки ...
  • 0
    Не пытайтесь войти в процесс, просто примените стилизацию с помощью ng-class и пусть процесс дайджеста позаботится об этом за вас!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню