本文介绍了使用 angularjs 创建一个新指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在制作一个名为hover"的简单指令,它是一个基本的导航菜单,当您将鼠标移到特定的 aba 上时,这个 aba 会改变颜色.看我的脚本代码:

so i'm making a simple directive called "hover", it's a basic nav menu that when you pass a mouse over a specific aba, this aba changes the color. See my script code:

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:

And now my 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 时:

This is working fine, but when i put my html in this way:

<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的一个坏技巧?

This doesn't work, i have to wrap my "li" with "hover" tag to make this work(and yes, i'm changing the restrict property to "A"), why? And another question, wrapping my "li" with "hover" tag is a bad trick to validation my html?

这是我编译的html:

This is my html compiled:

<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".

When i pass the mouse over these elements, my function: "onHover" doesn't is called.

推荐答案

首先澄清一下..

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

    • I do not recommend overusing $compile, there are better ways for binding event listeners to a scope.
    • I solved this question for me to learn how compilation works and to share it with others.
      • 编译阶段向下迭代 DOM,从父元素到子元素.
      • 当您在 compile 函数中操作 DOM 元素的子元素时,它发生在 $compile 深入到这些子元素以收集它们的指令之前,因此您对模板元素的内容所做的每一次更改将随着编译阶段的继续进行编译和链接.
      • 当您操作模板元素本身时,情况并非如此,然后 $compile 将不会在同一元素中查找更多指令,因为它仅收集每个 DOM 元素一个指令.
      • 所以你添加的这些属性没有被编译!
      • The compilation phase iterates down the DOM , from parent to children element.
      • When you manipulate children of a DOM element inside a compile function it happens before $compile got down to these children elements to collect their directives, so every change you make to the contents of the template element will be compiled and linked with the continuation of the compilation phase.
      • This is not the case when you manipulate the template element itself , then $compile will not look for more directives in that same element because it's only collecting directives once per each DOM element.
      • So these attributes you added are just not being compiled!
      • 我尝试添加 $compile(el) 但我的浏览器崩溃了(别笑我),原因是它陷入了无限循环自行编译.
      • 所以我删除了指令属性,然后再次$compile.
      • 我设置了 { priority:1001 } and { terminal:true }.这是为了防止其他指令编译函数在我们的指令之前或手动编译之后运行.
      • I tried to add $compile(el) but my browser crashed (don't laugh at me), The reason is it got into a loop where it's infinitely compiling itself.
      • So I removed the directive attribute and then $compile again.
      • I set { priority:1001 } and { terminal:true }. This iss needed to prevent other directive compile functions to run before our directive or after out manual compiling.

      这是一个plunker:http://plnkr.co/edit/x1ZeigwhQ1RAb32A4F7Q?p=preview

      here is a plunker: 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); //
            }
          }
        }
      });
      

      这篇关于使用 angularjs 创建一个新指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 15:34