我决定编写一个自定义指令来帮助我验证输入框。这个想法是,我将新的fancy nx-validate指令添加到引导程序中div.form- group,它将检查my <input/>is $dirty或is $invalid并根据需要应用.has-successor .has-error类。
nx-validate
div.form- group
<input/>
$dirty
$invalid
.has-success
.has-error
出于某种奇怪的原因,我的指令在正常情况下可以正常工作,但是在ng-classui-bootstrap模态内部完全忽略了添加的指令。
ng-class
模态和形式相同的代码
<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); } } } });
在插件上查看:http ://plnkr.co/edit/AjvNi5e6hmXcTgpXgTlH 吗?
我建议您使用的最简单方法是,可以通过在这些字段上使用watch来放置这些类,这watcher将postlink在编译DOM之后位于函数内
watcher
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'); }) }
在这里演示
更新资料
实际的更好方法是代替编译元素,我们需要函数本身$compile的元素link。在链接fn中使用DOM进行编译的原因$compile是,我们的ng- class属性确实包含范围变量,例如myForm.name.$invalid,因此,当我们$compile使用DOM编译功能时,myForm.name.$invalid由于编译无法访问范围,因此它们不评估变量的值。永远是undefined或blank。因此,尽管在内编译DOM时link将具有所有包含的作用域值,myForm.name.$invalid所以在使用指令作用域进行编译后,您将获得ng- class指令绑定有效的功能。
$compile
link
ng- class
myForm.name.$invalid
undefined
blank
码
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