Создание новой директивы с угловыми

поэтому я делаю простую директиву под названием "hover" , это базовое навигационное меню, которое, когда вы передаете указатель мыши на определенный aba, этот aba меняет цвет. Смотрите мой код script:

var app = angular.module('myModule', []);
app.directive('hover', function(){
    return{
        restrict: 'E',
        controller: function($scope) {
            $scope.hover    = null;
            $scope.selected = null;

            $scope.onHover = function (index){
                $scope.hover = index;
            }
            $scope.mouseLeave = function(){
                if($scope.selected)
                    $scope.hover = $scope.selected;
                else
                    $scope.hover = -1;
            }
            $scope.onClick = function(index) {
                $scope.hover    = index;
                $scope.selected = index;
            }

        },
        compile: function(el, attrs){
            el.children().attr('data-ng-mouseover', 'onHover('+attrs.index+')');
            el.children().attr('data-ng-mouseleave', 'mouseLeave()');
            el.children().attr('data-ng-click', 'onClick('+attrs.index+')');
            el.children().attr('data-ng-class', '{'+ attrs.onhover +': hover == ' + attrs.index + ' || selected == ' + attrs.index + '}');
        }
    }
});

И теперь мой html:

<ul>
    <hover index="0" onhover="hover"><li>Home</li></hover>
    <hover index="1" onhover="hover"><li>About Us</li></hover>
    <hover index="2" onhover="hover"><li>Contact</li></hover>
    <hover index="3" onhover="hover"><li>Share with us!</li></hover>
</ul>

Это работает нормально, но когда я помещаю свой html таким образом:

<ul>
    <li hover index="0" onhover="hover">Home</li>
    <li hover index="1" onhover="hover">About Us</li>
    <li hover index="2" onhover="hover">Contact</li>
    <li hover index="3" onhover="hover">Share with us!</li>
</ul>

Это не работает, я должен обернуть свой "li" тегом "hover" , чтобы сделать эту работу (и да, я изменяю свойство ограничения на "A" ), почему? И еще один вопрос, обертывание моего "ли" тегом "hover" - плохой трюк для проверки моего html?

Это мой html скомпилированный:

<ul>
<li onhover="hover" index="0" hover="" data-ng-mouseover="onHover()">Home</li>
<li onhover="hover" index="1" hover="" data-ng-mouseover="onHover()">About Us</li>
<li onhover="hover" index="2" hover="" data-ng-mouseover="onHover()">Contact</li>
<li onhover="hover" index="3" hover="" data-ng-mouseover="onHover()">Share with us!</li>
</ul>

Когда я пропускаю мышь над этими элементами, моя функция: "onHover" не вызывается.

Ответ 1

Сначала уточнение..

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

что происходит при манипулировании элементом шаблона внутри compile function?

  • Фаза компиляции выполняет итерацию по DOM, от элемента parent до children.
  • Когда вы манипулируете дочерними элементами элемента DOM внутри функции компиляции, это происходит до того, как $compile перешел к этим дочерним элементам, чтобы собрать их директивы, поэтому каждое изменение, которое вы делаете на содержимое элемента шаблона, будет скомпилировано и связано с продолжение фазы компиляции.
  • Это не тот случай, когда вы управляете самим элементом шаблона, тогда $compile не будет искать больше директив в том же элементе, потому что он только для сбора директив один раз за каждый элемент DOM.
  • Итак, эти добавленные вами атрибуты просто не компилируются!

Позволяет компилировать его вручную:

  • Я попытался добавить $compile(el), но мой браузер разбился (не смейтесь надо мной). Причина в том, что он попал в цикл, где он бесконечно компилирует себя.
  • Итак, я удалил атрибут директивы, а затем $compile снова.
  • Я установил { priority: 1001} и { terminal: true}. Это необходимо для предотвращения выполнения других функций компиляции директивы перед нашей директивой или после ручной компиляции.

Решение:

вот плукер: http://plnkr.co/edit/x1ZeigwhQ1RAb32A4F7Q?p=preview

app.directive('hover', function($compile){
  return{
    restrict: 'A',
    controller: function($scope) {

       // all the code
    },

    priority: 1001, // we are the first

    terminal: true, // no one comes after us

    compile: function(el, attrs){

      el.removeAttr('hover'); // must remove to prevent infinite compile loop :()

      el.attr('data-ng-mouseover', 'onHover('+attrs.index+')');
      el.attr('data-ng-mouseleave', 'mouseLeave()');
      el.attr('data-ng-click', 'onClick('+attrs.index+')');
      el.attr('data-ng-class', '{'+ attrs.onhover +': hover == ' + attrs.index + ' || selected == ' + attrs.index + '}');

      var fn =  $compile(el); // compiling again

      return function(scope){
        fn(scope); //
      }
    }
  }
});