AngularJS自定义表单验证指令不中我的工作模式 [英] AngularJS custom form validation directive doesn't work in my modal

查看:213
本文介绍了AngularJS自定义表单验证指令不中我的工作模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定写一个自定义的指令来帮我验证我的输入框。这个想法是,我在我的新花式 NX-验证指令添加到引导 div.form组和它' LL检查是否我的<输入/> $脏 $无效和适用。先后-成功。先后误差为所需的类。

I decided to write a custom directive to help me validate my input boxes. The idea is that I add my new fancy nx-validate directive to a bootstrap div.form-group and it'll check whether my <input/> is $dirty or $invalid and apply the .has-success or .has-error class as required.

有关一些奇怪的原因,我的指导工作完全正常的情况下,但增加的纳克级完全是一个用户界面,引导模式里忽略。

For some odd reason, my directive works perfectly under normal circumstances, but the added ng-class is completely ignored inside a ui-bootstrap modal.

相同code的模式和形式都

<form name="mainForm">
  <div class="row">
      <div nx-validate class="form-group has-feedback col-lg-6 col-md-6 col-xs-12">
          <label class="control-label">Green if long enough, red if not</label>
          <input type="text" id="name" class="form-control" ng-model="property.name" required="required" ng-minlength="5"/>
          (once touched I do change colour - happy face)
      </div>
  </div>        

我的可爱的指令

nitro.directive("nxValidate", function($compile) {
    return {
        restrict: 'A',
        priority: 2000,
        compile: function(element) {

            var node = element;
            while (node && node[0].tagName != 'FORM') {
                console.log (node[0].tagName)
                node = node.parent();
            }
            if (!node) console.error("No form node as parent");
            var formName = node.attr("name");
            if (!formName) console.error("Form needs a name attribute");


            var label = element.find("label");
            var input = element.find("input");
            var inputId = input.attr("id")

            if (!label.attr("for")) {
                label.attr("for", inputId);
            }

            if (!input.attr("name")) {
                input.attr("name", inputId);
            }

            if (!input.attr("placeholder")) {
                input.attr("placeholder", label.html());
            }

            element.attr("ng-class", "{'has-error' : " + formName + "." + inputId + ".$invalid && " + formName + "." + inputId + ".$touched, 'has-success' : " + formName + "." + inputId + ".$valid && " + formName + "." + inputId + ".$touched}");
            element.removeAttr("nx-validate");

            var fn = $compile(element);

            return function($scope) {
                fn($scope);
            }

        }
    }
});

检查出来的plunker: http://plnkr.co/edit/AjvNi5e6hmXcTgpXgTlH

推荐答案

我建议你最简单的方法是,你可以通过对这些领域的关注,这观察家将躺在 postlink 函数内部编译后的DOM

The simplest way I'd suggest you is you can put those classes by using watch on those fields, this watcher will lie inside the postlink function after compiling a DOM

return function($scope, element) {
    fn($scope);

    $scope.$watch(function(){
      return $scope.modalForm.name.$invalid && $scope.modalForm.name.$touched;
    }, function(newVal){
      if(newVal)
        element.addClass('has-error');
      else
        element.removeClass('has-error');
    })

    $scope.$watch(function(){
      return $scope.modalForm.name.$valid && $scope.modalForm.name.$touched;
    }, function(newVal){
      if(newVal)
        element.addClass('has-success');
      else
        element.removeClass('has-success');
    })
}

演示这里

更新

这样做的实际更好的方式是,而不是从编译编译元素,我们需要 $编译链接元素函数本身。在链接编译DOM背后的原因FN使用 $编译是我们的纳克级属性确实包含的范围变量这就好比 myForm.name。$无效,所以当我们 $编译编译功能的DOM然后他们不是。评估 myForm.name $无效变量的值,因为编译没有访问范围和放大器;该会总未定义空白。因此,尽管内部链接编译DOM 将拥有所有的范围值可用,它包含 myForm.name。$无效所以用指令的范围,你会得到你的纳克级指令结合将工作编译后。

The actual better way of doing this would be instead of compiling element from compile, we need $compile the element from the link function itself. The reason behind the compiling DOM in link fn using $compile is that our ng-class attribute does contain the scope variable which is like myForm.name.$invalid ,so when we $compile the DOM of compile function then they are not evaluating value of myForm.name.$invalid variable because compile don't have access to scope & the would be always undefined or blank. So while compile DOM inside the link would have all the scope values are available that does contain myForm.name.$invalid so after compiling it with directive scope you will get your ng-class directive binding will work.

code

compile: function(element) {
    //..other code will be as is..

    element.removeAttr("nx-validate");
      //var fn = $compile(element); //remove this line from compile fn
      return function($scope, element) {
         //fn($scope);
         $compile(element)($scope); //added in postLink to compile dom to get binding working
      }
 }

更新Plunkr

这篇关于AngularJS自定义表单验证指令不中我的工作模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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