AngularJS指令$ compile导致ng-click触发两次 [英] Angularjs directive $compile causing ng-click to fire twice

查看:78
本文介绍了AngularJS指令$ compile导致ng-click触发两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个用于表单验证的角度验证器模块,而无需在表单中包含ngMessages,并且一切都按预期工作.

I created an angular validator module for form validation without the need to include ngMessages in the form and everything is working as expected.

但是,我发现了一个我一直试图修复的错误.它与 $ compile 有关.

However I discovered a bug which I have been trying to fix. It has something to do with $compile.

所以我有一条指令,可以向表单元素添加属性,这可以通过使用$ compile服务来实现,但是,似乎$ compile服务会导致 ng-click 出现有害行为,因此当 ng-click 会被触发两次;

So I have a directive that adds attributes to form elements and this is achieved by using $compile service however, it seems the $compile service causes an unwanted behaviour to ng-click so when ng-clicklocated inside the form is called it fires twice;

这是指令以及我在做什么:

Here is the directive and what I am doing:

angular.module('app',[])

.directive('validateForm',['$compile',
        function($compile)
        {
            var addErrors = function(rules, form, ctrls, scope, config){
                //code
            };


            return {
                restrict: 'A',
                require: ['^form'],
                link: {
                    post: function(scope, element, attrs, ctrls){

                        var form = ctrls[0];
                        var config = scope.validator;

                        if(typeof config != 'object') return;

                        var rules = config['rules'];
                        var errors = [];

                        //-----
                    },
                    pre: function(scope, element, attrs, ctrls){

                        var elm = element.find('select, input, textarea').attr('validate-field','');
                        element.removeAttr("validate-form"); //remove the attribute to avoid indefinite loop
                        element.removeAttr("data-validate-form");
                        $compile(element.contents())(scope);
                    }
                }
            };
        }

    ])
 .controller('UserController',['$scope', function($scope){
  $scope.title = 'Form Validator';
  $scope.clickThings = function(value){
    alert(value); //pops up twice means ng-click fires twice
  }
}]);

表单标记:

 <div ng-controller="UserController">
 <form novalidate="" validate-form name="form" role="form">
     <div class="form-group">
          <input type="text" class="form-control" ng-model="first_name" name="first_name" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ng-model="last_name" name="last_name" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ng-model="email" name="email" />
        </div>
        <div class="form-group">
          <input type="password" class="form-control" ng-model="password" name="password" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ng-model="country" name="country" />
        </div>
        <a type="button" class="btn btn-success" ng-click="clickThings('Submit Clicked')">Submit</a>
      </form>
      </div>

我创建了一个塞子: http://embed.plnkr.co/uIid4gczKxKI4rPOHqx7

推荐答案

尝试了不同的方法后,我意识到已经编译的 ng-click $ compile(element.contents())(scope)被调用.

After trying different things I realized ng-click which is already compile is compiled a second time when $compile(element.contents())(scope) is called.

要解决此问题,只需编译更改/受影响的元素,即 elem = element.find('select,input,textarea').attr('validate-field','');

To resolve this issue, only need to compile the altered/affected elements i.e elem = element.find('select, input, textarea').attr('validate-field','');

通过将 $ compile(element.contents())(scope)替换为 $ compile(elem)(scope);

所以我最终得到了这个

angular.module('app',[])

.directive('validateForm',['$compile',
    function($compile)
    {
        var addErrors = function(rules, form, ctrls, scope, config){
            //code
        };

        return {
            restrict: 'A',
            require: ['^form'],
            link: {
                post: function(scope, element, attrs, ctrls){

                    var form = ctrls[0];
                    var config = scope.validator;

                    if(typeof config != 'object') return;

                    var rules = config['rules'];
                    var errors = [];

                    //-----
                },
                pre: function(scope, element, attrs, ctrls){

                    var elem = element.find('select, input, textarea').attr('validate-field','');
                    element.removeAttr("validate-form"); //remove the attribute to avoid indefinite loop
                    element.removeAttr("data-validate-form");
                    $compile(elem)(scope);
                }
            }
        };
    }

 ])
 .controller('UserController',['$scope', function($scope){
   $scope.title = 'Form Validator';
   $scope.clickThings = function(value){
   alert(value); //pops up twice means ng-click fires twice
  }
 }]);

在这里工作的打工者:

这篇关于AngularJS指令$ compile导致ng-click触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆