所以我正在制作一个名为“悬停”的简单指令,它是一个基本的导航菜单,当你将鼠标移到特定的aba上时,这个aba会改变颜色.看我的脚本代码:
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”以使其工作(是的,我将限制属性更改为“A”),为什么?还有一个问题,用“悬停”标签包装我的“li”是验证我的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>
解决方法
首先澄清..
>我不建议过度使用$compile,有更好的方法将事件侦听器绑定到作用域.
>我解决了这个问题,让我了解编译的工作原理并与他人分享.
在编译函数中操作模板元素时会发生什么?
>编译阶段迭代DOM,从parent元素到子元素.
>当你在编译函数中操作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); // } } } });