Javascript AngularJS自定义表单验证指令不';我不能在我的房间工作

Javascript AngularJS自定义表单验证指令不';我不能在我的房间工作,javascript,angularjs,html,twitter-bootstrap,angularjs-directive,Javascript,Angularjs,Html,Twitter Bootstrap,Angularjs Directive,我决定编写一个自定义指令来帮助我验证输入框。我的想法是将新的fancynx validate指令添加到引导div.form-group中,它将检查我的是$dirty还是$invalid并根据需要应用.has success或has error类 出于某种奇怪的原因,我的指令在正常情况下工作得很好,但是在ui引导模式中,添加的ng类被完全忽略 模态和形式中的相同代码 <form name="mainForm"> <div class="row"> <d

我决定编写一个自定义指令来帮助我验证输入框。我的想法是将新的fancy
nx validate
指令添加到引导
div.form-group
中,它将检查我的
$dirty
还是
$invalid
并根据需要应用
.has success
has error

出于某种奇怪的原因,我的指令在正常情况下工作得很好,但是在ui引导模式中,添加的
ng类
被完全忽略

模态和形式中的相同代码

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

在plunker上查看:?

我建议您的最简单方法是,您可以使用watch将这些类放在这些字段上,编译DOM后,这个
观察者将位于
postlink
函数中

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');
    })
}

更新

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);
            }

        }
    }
});
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
      }
 }
实际上更好的方法是不从compile编译元素,我们需要
$compile
链接
函数本身编译元素。使用
$compile
在link fn中编译DOM的原因是我们的
ng class
属性确实包含类似于
myForm.name.$invalid
的范围变量,因此,当我们
$compile
编译函数的DOM时,它们不是在计算
myForm.name.$invalid
变量的值,因为compile没有访问范围的权限&它总是
未定义的
空白的
。因此,当编译
链接中的DOM时,
将具有所有包含
myForm.name.$invalid
的作用域值,因此使用指令作用域编译后,您将获得
ng类
指令绑定

代码

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);
            }

        }
    }
});
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
      }
 }

将按钮放在表单中。当我在plunker示例中这样做时,它对我很有用。谢谢你的回答。你能解释一下为什么我的例子在默认情况下不起作用吗。除了想解决这个问题——我相信你的答案会解决这个问题,我还想理解为什么我首先会遇到这个问题,并且能够避免它在将来发生。是因为模态内容是动态的,并且我的指令具有错误的优先级,还是在错误的时间编译,或者你认为这是一个范围问题吗?@Spider很抱歉反应太晚。请看我更新的答案。现在应该可以了。我认为这是编译问题,因为
ng class
@Spider你看了答案了吗?太棒了。非常感谢。你能给我指一个我可以研究细节的资源,这样我就可以正确地理解它吗?@Spider no没有任何官方文件可以阅读这篇文章。我希望你阅读这篇文章,这篇文章能帮助你更清楚地了解这一点。。