Ответ 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); //
}
}
}
});