Сделать изменение цвета фона при зависании после установки стиля с помощью ng-стиля

У меня есть список слов с числом (полосой), назначенным каждому слову. Я устанавливаю цвет фона каждого слова на основе присвоенного ему номера с помощью AngularJS ng-style.

HTML

   <ul class="unstyled">
     <li class="tHi" ng-repeat="item in items" ng-click="getEdit(item.word)" ng-style="bgstyle(item.streak)">
       <span>{{item.word}} {{item.streak}}</span>
     </li>
   </ul>

javascript, который вызывается из ng-стиля.

$scope.bgstyle = function (streak) {
    var red = 255;
    var green = 255-streak;
    var blue = 255-streak;
    var rgb = blue | (green << 8) | (red << 16);
    var sColor = '#' + rgb.toString(16);
    return {backgroundColor: sColor};
}

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

Вот jsfiddle, который демонстрирует эту проблему.

Есть ли лучший способ установить фон, чем стиль ng, чтобы он соответствовал числу, присвоенному каждому слову? Или есть способ выделить, когда пользователь наводит курсор на слово?

Ответ 1

Это один из немногих случаев, когда я действительно предлагаю использовать !important в CSS:

.tHi:hover {
    cursor: pointer;
    background-color: #9f9 !important;
}

Обновленная демонстрация JS Fiddle.

Использование ключевого слова !important по существу приводит к тому, что правило применяется независимо от специфики селектора (при условии, что более специфичный селектор также не имеет ключевое слово !important, конечно). Тем не менее, у него есть возможность сделать отладку довольно сложной, если вы или ваши коллеги забыли об использовании !important.

Литература:

Ответ 2

Если вы не хотите использовать !important, вы можете добавить класс динамически, используя ng-mouseover:

 <li ng-repeat="item in items" ng-click="getEdit(item.word)" 
    ng-style="bgstyle(item.streak)" ng-mouseover="hover($event)">

Затем добавьте к контроллеру:

$scope.hover = function(e) {
    angular.element(e.srcElement).addClass('tHi')
}

Манипуляция DOM в контроллере не является "лучшей практикой". Директива будет лучше.

Обновление: Здесь директива

myApp.directive('ngHover', function() {
  return {
    link: function(scope, element) {
       element.bind('mouseenter', function() {
          angular.element(element.children()[0]).addClass('tHi')
       })
    }
  }
});

children()[0] используется для применения класса к span, а не к li, чтобы не противоречить стилю ng.

Используйте следующее:

<li ng-repeat="item in items" ng-click="getEdit(item.word)"
  ng-style="bgstyle(item.streak)" ng-hover>

Fiddle

Ответ 3

Я нашел в директиве самый простой способ.

App.directive('attr', function(){
    return function(scope, element) {
        element.bind('mouseenter', function(){
            element.addClass('hover');
        }).bind('mouseleave', function(){
          element.removeClass('hover');
        })
    }
})