简体   繁体   English

在指令中调用$ compile($ element)($ scope)的目的是什么

[英]What is the purpose of calling $compile($element)($scope) in a directive

The angular code placed on jsfiddle is regarding a custom directive, that uses $compile($element)($scope) and causes the ng-click action to happen twice: My questions are: 放在jsfiddle上的角度代码与一个自定义指令有关,该指令使用$compile($element)($scope)并导致ng-click动作发生两次:我的问题是:

  • I would like to understand, why is the ng-click action happening twice? 我想了解,为什么ng-click动作会发生两次?
  • What is the purpose of calling $compile($element)($scope) ? 调用$compile($element)($scope)的目的是什么?
  • what happens if it is not called, under what circumstances should it be called? 如果不调用它会发生什么情况,在什么情况下应该调用它?

Here are the details and what I have gathered so far: 以下是详细信息以及到目前为止我收集的内容:

I would like to understand, why is the ng-click action happening twice? 我想了解,为什么ng-click动作会发生两次? The following line shows the custom directive "hello" and ng-click on a button. 下一行显示了自定义指令“ hello”,然后在按钮上进行ng单击。 The custom directive calls $compile($element)($scope) and that is the line that causes the action being fired twice, but I don't understand how? 自定义指令调用$compile($element)($scope) ,这是导致操作被触发两次的行,但是我不知道该怎么做?

Test CLICK! 测试点击!

Here is the code - http://jsfiddle.net/4x4L3gtw/27/ 这是代码-http://jsfiddle.net/4x4L3gtw/27/

<div ng-app='myApp' ng-controller='DirectiveTestController'>
    <button hello ng-click="testClick()">Test CLICK!</button>
</div>

var myApp = angular.module('myApp', []);
myApp.controller('DirectiveTestController', ['$scope',

function ($scope) {
    $scope.testClick = function () {
        window.alert("hey");
        console.log("hey");
    }
}]);
myApp.directive('hello', function () {
    return {
        scope: true,
        controller: ['$scope', '$element', '$compile', function ($scope, $element, $compile) {
            $element.removeAttr('hello');
            //          $element.removeAttr('ng-click');
            $compile($element)($scope);
        }]

    };
});

What is the purpose of calling $compile($element)($scope) , what happens if it is not called and under what circumstances should it be called? 调用$compile($element)($scope)的目的是什么,如果不调用它将发生什么情况,在什么情况下应该调用它?

(click on the button and you will notice that the action happens twice) (单击按钮,您将注意到该操作发生了两次)

The intent of the directive is to hide/disable based on some logic. 该指令的目的是基于某些逻辑来隐藏/禁用。 so in this directive I see $element.removeAttr("ng-hide") , etc, and each time the $element.removeAttr is called it is followed with a $compile($element)($scope) , is the purpose to re-write the DOM? 因此,在此指令中,我看到$element.removeAttr("ng-hide")等,并且每次调用$element.removeAttr ,其后都是$compile($element)($scope) ,目的是重新编写DOM?

I examined the DOM and I don't see ng-click defined multiple times. 我检查了DOM,但没有看到多次定义ng-click。 When examining the DOM (firebug), I looked at $element->0->attributes->ng-click (among other elements). 在检查DOM(萤火虫)时,我查看了$ element-> 0-> attributes-> ng-click(以及其他元素)。

If I remove ng-click using $element.removeAttr("ng-click") then the action only happens once. 如果我使用$element.removeAttr("ng-click")删除ng-click,则该操作仅发生一次。 Or if I remove the $compile($element)($scope) the action only happens once. 或者,如果我删除了$compile($element)($scope)该操作只会发生一次。

I think the main reason why this is happening is because you are using a click event in the element where you apply the directive, instead of defining this event directly in the directive. 我认为发生这种情况的主要原因是因为您在应用指令的元素中使用了click事件,而不是直接在指令中定义此事件。 Therefore you are getting the click from the button element, but also the click from the directive controller. 因此,您将获得来自button元素的点击,还获得来自指令控制器的点击。

What $compiles do is once invoked against markup will produce a function you can use to bind the markup against a particular scope (what Angular calls a linking function), that's why Rodion suggested using link, I guess. 一旦针对标记调用了$ compiles函数,将产生一个函数,您可以使用该函数将标记绑定到特定范围(Angular称为链接函数),这就是Rodion建议使用链接的原因。 In this particular case, it means that you are are using an event directly in the element button but then linking it again to the scope in your directive by using $compile. 在这种情况下,这意味着您直接在元素按钮中使用事件,然后通过使用$ compile将其再次链接到指令中的作用域。 I guess that's why you get the message twice. 我想这就是为什么您两次收到消息的原因。

As I don't know whether this is clear, I obtained the information from this link http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx where it is way better explained. 我不知道这是否清楚,因此我从此链接http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx中获取了信息更好的解释。

Here also a JSFiddle where you can see how it works (excerpt from the article above). 这里还有一个JSFiddle,您可以在其中查看其工作原理(摘自上面的文章)。

app.directive("otcDynamic", function($compile){
   return {
        link: function(scope, element){
            var template = "<button ng-click='doSomething()'>{{label}}</button>";
            var content = $compile(template)(scope);
            element.append(content);
        }
    };
});

JSFiddle JSFiddle

I think such operations (with html) should be in link (not in controller): 我认为这样的操作(使用html)应该在链接中(而不是在控制器中):

link: function (scope, element) { element.removeAttr('hello'); }

http://jsfiddle.net/4x4L3gtw/32/ http://jsfiddle.net/4x4L3gtw/32/

compile - $compileProvider - service in module ng Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together. ng模块中的compile-$ compileProvider-服务将HTML字符串或DOM编译为模板并生成模板函数,然后可将其用于将范围和模板链接在一起。

The compilation is a process of walking the DOM tree and matching DOM elements to directives. 编译是遍历DOM树并将DOM元素与指令匹配的过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM