使用angularjs创建一个新指令

Rod*_*eca 5 angularjs angularjs-directive

所以我正在制作一个名为"悬停"的简单指令,它是一个基本的导航菜单,当你将鼠标移到特定的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 + '}');
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

现在我的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>
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是当我以这种方式放置我的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>
Run Code Online (Sandbox Code Playgroud)

这不起作用,我必须用"悬停"标签包装我的"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>
Run Code Online (Sandbox Code Playgroud)

当我将鼠标移到这些元素上时,我的函数:"onHover"不会被调用.

Ila*_*mer 13

首先澄清..

  • 我不建议过度使用$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); //
      }
    }
  }
});
Run Code Online (Sandbox Code Playgroud)