使用 angularjs 创建一个新指令

Posted

技术标签:

【中文标题】使用 angularjs 创建一个新指令【英文标题】:creating a new directive with angularjs 【发布时间】:2014-02-14 10:08:19 【问题描述】:

所以我正在制作一个名为“hover”的简单指令,它是一个基本的导航菜单,当你将鼠标移到特定的 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>

这不起作用,我必须用“hover”标签包裹我的“li”才能使其工作(是的,我正在将限制属性更改为“A”),为什么?还有一个问题,用“hover”标签包裹我的“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>

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

【问题讨论】:

您将指令限制为E 类型,如Element,您需要查看其他限制类型、类、属性等。听起来您可能想要restrict: 'A' restrict: 'E',意思是“限制做元素”改成restrict: 'A',意思是“限制属性” 对不起,我现在更新了,但是我把属性改成了“A”。 【参考方案1】:

首先澄清一下..

我不建议过度使用$compile,有更好的方法可以将事件监听器绑定到作用域。 我解决了这个问题,让我了解编译的工作原理并与他人分享。

compile function 中操作模板元素时会发生什么?

编译阶段向下迭代 DOM,从父元素到子元素。 当您在编译函数中操作 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); //
      
    
  
);

【讨论】:

“我设置了 priority:1001 和 terminal:true 。这是为了防止其他指令编译函数在我们的指令之前或手动编译之后运行。”好的,但是如果我想使用另一个带有编译功能的指令?你说绑定事件监听器存在更好的选择,更好的选择是什么?还有,感谢您的解释。 我会在有时间的时候更新我的答案。我发现了一个类似的问题:***.com/questions/19224028/…

以上是关于使用 angularjs 创建一个新指令的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 指令实践指南

angularjs 指令(directive)详解

AngularJS 指令的 Scope (作用域)

AngularJS

AngularJS 指令的 Scope (作用域)

angularJs指令的Scope(作用域)