角度动态要求对字段高亮的字段组进行验证,如果无效 [英] Angular dynamic required validation of group of fields with field highlight if invalid

查看:188
本文介绍了角度动态要求对字段高亮的字段组进行验证,如果无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新1:根据评论的反馈,问题将得到加强。

更新2:已经取得了一些进展。需要补充帮助才能通过。请阅读以下内容。

更新3:使用 $ compile(el [0])(scope);

编译元素时,提供的示例代码中的错误修复导致表行中的重复code>。

在页面加载时,从数据库中检索字段名称列表,该列表指示使用ajax调用需要哪些字段 getRequiredFieldInfo ()。在执行指令 check-if-required 之前执行相关的角度代码以操纵所需的属性。该指令必须循环所有输入字段,并根据从数据库检索的列表标记它们。



我做了一些研究,发现这个帖子似乎最接近我的要求:



https://stackoverflow.com/ a / 28207652/4180447



,最后在这里(更新)找到了一个工作的jsfiddle版本:



http://jsfiddle.net/tarekahf/d50tr99u/



我可以使用以下简单的方法:

 < input name =firstNametype =文本foo ng-required =isFieldRequired('firstName')/> 

函数 isFieldRequired()将检查是否在列表中找到传递的字段名称,它将返回true。



这种方法的问题是我必须将这个函数添加到每一个字段中需要。



此外,每次都必须传递字段名称。为了更有效率,我将不得不使用父元素 div fieldset 的指令,这将允许我访问所有子元素,并处理所有输入元素所需的属性。



此伪指令需要更改如下:




  • 要添加到必需属性的字段组的父元素将被处理和修改如果


  • 将元素名称与要设置的字段列表进行比较,并相应地应用更改。




更新的代码(正在研究解决方案):



STYLE

  input.ng-invalid,li.ng-invalid {
background:#F84072;
border:2px red solid;
}

HTML - 导航表:

 < ul class =nav nav-pills> 
< li ng-class ={'ng-invalid':mainForm.homeForm。$ invalid&& mainPromiseResolved}class =active>< a data-toggle =pillhref = #家 ><%= homeTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.clientForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu1 ><%= clientTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.appraiserForm。$ invalid&& mainPromiseResolved}> < a data-toggle =pillhref =#menu2><%= appraiserTabName%>< / a>< / li>
< li ng-class ={'ng-invalid':mainForm.propertyForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu3 ><%= propertyTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.serviceForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu4 ><%= servicesTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.constructionStage。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu5 ><%= constructionStageTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.costForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu6 ><%= costTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.certificationForm。$ invalid&& mainPromiseResolved}ng-click =redrawCanvas()>< a data-toggle = pillhref =#menu7><%= certificationTabName%>< / a>< / li>
< li ng-class ={'ng-invalid':mainForm.photosForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu8 ><%= photoTabName%GT;< / A>< /锂>
< li ng-class ={'ng-invalid':mainForm.mapForm。$ invalid&& mainPromiseResolved}>< a data-toggle =pillhref =#menu9 ><%= locationTabName%GT;< / A>< /锂>
< / ul>

HTML - 表单

 < div id =menu2class =tab-pane fadeng-form =appraiserForm> 
< fieldset ng-disabled =isAppraiserSigned()check-if-required>
< input type =textid =appraiser_namename =appraiser_nameng-model =sigRoles.appraiser.roleNameModelstyle =width:536px;>
< input type =textid =appraiser_companystyle =width:536px;>
...
...
< / fieldset>
< / div>

Javascrip:

  app.controller('formMainController',['$ scope','$ timeout','$ q',function($ scope,$ timeout,$ q){

$ scope.runProcessAndInit = function(){
var q = $ q.defer(); //创建承诺控制器
angular.element(document).ready(function ){
//在这里执行所有客户端更新
q.resolve('success'); //通知执行成功完成 - 在文档'ready'事件内
})
return q.promise; //返回promise对象
}
// mainPromiseResolved用于指示所有的ajax调用和客户端更新完成
$ scope.mainPromiseResolved = false;
$ scope.mainPromise = $ scope.runProcessAndInit();
$ scope.mainPromise.then(function(success){
// debugger;
$ scope。$ broadcast('事件:force-model-update');
// mainPromiseResolved主要用于角度验证,以防止在完成所有客户端更新之前显示错误。
$ scope.mainPromiseResolved = true;
return'main promise done';
})
$ scope.isFieldRequired = function(prmFieldName){
var isFound = false;
var oRequiredField = formView.getRequiredField();
findField:{
for(var subformName in oRequiredField){
isFound = prmFieldName in oRequiredField [subformName];
if(isFound){
break findField;
}
}
}
return isFound;
}
函数getRequiredFieldInfo(){
var q = $ q.defer();
var appUrl = getAppURL();
$ .get(appUrl +/ servlet / ...
+& timestamp =+ new Date()。getTime(),
function(data,status){
//console.log(\" json fields:+ data);
var obj = JSON.parse(data);
formView.setRequiredField(obj);
q。 resolve('success');
// console.log(JSON.stringify(formView.getRequiredField()));
});
return q.promise;
}
$ scope.requiredFieldsPromise = getRequiredFieldInfo();
}]);

app.directive('checkIfRequired',['$ compile',function($ compile){
return {
require:'?ngModel',
link :function(scope,el,attrs,ngModel){
if(!ngModel){
// return;
}
// debugger;
var children = $(:input,el);
angular.element(document).ready(function(){
scope.requiredFieldsPromise.then(function(success){
// remove the属性以避免递归调用
el.removeAttr('check-if-required');
//下面的注释行,因为它导致表raws中的重复,我不知道为什么
// $ compile(el [0])(scope);
angular.forEach(children,function(value,key){
// debugger;
if(scope.isFieldRequired value.id)){
angular.element(value).attr('required',true);
//el.removeAttr('check-if-required');
$ compile(value)(scope);
}
});
})
})
}
};
}]);

我已经取得了一些进展。但是,我还需要更多的帮助。以下是状态:




  • 完成:从DB获取必需的字段列表,然后在指令中执行代码来操作
  • 完成:从给定的角度元素 el中循环子输入元素传递给链接函数 function(scope,el,attrs,ngModel)


  • 完成:将必需属性添加到每个子元素,如果 isFieldRequired(fieldName ) $ / $>

  • 完成:使用promise确保在执行角度代码之前完成所有的ajax数据库调用和客户端更新。 / p>


  • 如果将子元素嵌套在另一个 ng-form 子表单或 div 元素


  • 如何确保每个元素都有ngModel对象?


  • 如何将指令限制为 div fieldsset 或类似元素?




Tarek

解决方案

以下代码将满足主要要求,此外,对于 div 块下的每个元素,它将允许添加属性 check-if - 更换 - EXPR 。此新属性可用于调用范围布尔表达式以确定必需的属性,以防该字段未找到必填字段的列表。



我想知道是否有办法使用标准的 ng-required 指令而不是自定义属性 check-if-required-expr 其基本上与 ng-required 相同。如果我使用 ng-required ,唯一的问题是它可能会覆盖列表中指定的必填字段的逻辑。



所以这里的问题是:有没有办法找出是否设置了所需的属性,如果是,那么不要检查所需的表达式,



HTML



ng-class ={'ng-invalid':认证格式[theRoleData.signatureBase64]

。$ invalid&& mainPromiseResolved}check-if-required>
...
< div class =m-signature-pad - body>
< canvas id =appraiser_signature_sectionredraw ng-signature-pad =signatureng-hide =isSigned()>
< / canvas>
< img ng-src ={{signatureDataURL()}}ng-hide =!isSigned()load-signature-image>
< input id ={{theRoleData.signatureBase64}}name ={{theRoleData.signatureBase64}}type =textng-hide =trueng-model =signatureBase64 if-required-expr =sigDetailsAvail(theRoleData)force-model-update />
< / div>
...

< / div>

基本上,在上述HTML中,输入 check-if-required-expr 的字段表示如果在所需字段列表中找不到此字段然后执行表达式来决定是否需要该字段。



JavaScript



  //定义指令check-if-required 
//该指令将循环遍历所有子输入元素,如果需要,则添加必需的属性
app.directive('checkIfRequired',['$ ($ compile,$ timeout,$ parse){
return {
/ * require:'?ngModel',* /
要求:'?^ form',
link:function(scope,el,attrs,ngForm){
/ * if(!ngModel){
return;
}
var saveIsValidationRequired;
var children;
saveIsValidationRequired = scope.isValidationRequ ired; //保存当前标志值
scope.stopExecValidations();
el.removeAttr('check-if-required');
$ timeout(function(){
//获取'el'的后代的所有输入元素
children = $(:input,el);
//尽可能早地运行以下内容,但只需等待(使用promise)直到
//从数据库
检索所需字段的列表//scope.requiredFieldsPromise.then(function(success){
scope.requiredFieldsPromise.then(function(success){
//下面的行导致在构建阶段的表的重复,所以它被删除,没有影响
// $ compile(el [0] )(范围);
angular.forEach(children,function(child,key){
var elmScope;
var elmModel;
try {
if(child& ;& child.id){
elmScope = angular.element(child) .scope()||范围;
elmModel = angular.element(child).controller('ngModel');
if(ngForm&& elmModel& ngForm [elmModel。$ name]){
scope。$ watch(function(){
//观察定义的错误字段 - 转换为JSON字符串
返回JSON.stringify(ngForm [elmModel。$ name]。$ error);
},function(newValue,oldValue){
//验证错误
var maxlength;
var minlength;
if(angular.isDefined(newValue)){
if(ngForm [elmModel。$ name]。$ error.maxlength){
//如果无效,添加erro r消息,如果输入的字符数大于定义的最大值
maxlength = scope。$ eval(angular.element(child).attr('ng-maxlength'));
child.title =(输入的字符数不应超过{0}字符。)。format(maxlength);
} else {
//如果有效,请删除该错误。
child.removeAttribute('title');
}
}
});
}
if(scope.isFieldRequired(child.id)){
angular.element(child).attr('ng-required',true);
$ compile(child)(elmScope);
}
//检查元素是否不在必需列表中,它有一个表达式来控制需求,然后
// ...添加属性ng-required用表达式指定元素并进行编译。
if(!angular.element(child).prop('required')&&& child.attributes.hasOwnProperty(check-if-required-expr)){
var isRequiredExpr = child .attributes [ 检查是否要求的-EXPR]的孩子。
angular.element(child).attr('ng-required',isRequiredExpr);
$ compile(child)(elmScope);
}
var validObjects = scope.getFieldValidation(child.id);
if(angular.isArray(validObjects)){
for(var idx = 0; idx< validObjects.length; idx ++){
var validObject = validObjects [idx];
var test = validObject.test || 真正; //如果不存在,这意味着应该总是应用规则
var minLenExp = validObject.minlen;
var maxLenExp = validObject.maxlen;
var isRequiredExp = validObject.required ||假;
isRequiredExp = angular.isString(isRequiredExp)?isRequiredExp:isRequiredExp.toString();
//scope.$evalAsync(function(){
if(test&&(minLenExp || maxLenExp || isRequiredExp)){
var testEval = scope。$ eval ,elmScope);
if(testEval){
if(minLenExp){
angular.element(child).attr('ng-minlength',minLenExp);
}
if(maxLenExp){
angular.element(child).attr('ng-maxlength',maxLenExp);
}
//如果必需表达式为'*跳过*'然后简单地跳过
//如果使用'* skip *',这意味着所需的验证已经在代码
//中定义,并且不需要替换它。
if(isRequiredExp&& isRequiredExp!='* skip *'){
angular.element(child).attr('ng-required',isRequiredExp);
}
//更改如何使用'$ compile()'。
//在执行后,发现Angular中存在错误,导致使用'$ compile()'时的下列问题:
// 1.下拉列表项的重复值。
// 2.使用dateppciker进行Inteference Angular UI Bootstrap控件
//如果这还是很开心,需要更多的研究来解决这个问题。
//这仍然在进行中。需要更多的研究。
//下面的编译语句将被替换...
$ compile(child)(elmScope,function(clone){
angular.element(child).after(clone);
angular.element(child).remove();
});
//仅应用第一个匹配的验证规则
break;
}
}
}
}
}
} catch(e){
console.error(checkIfRequired指令,同时在元素ID'%s'上应用验证逻辑。错误是:'%s',child.id,e);
}
});
//如果保存的标志值为ture,则启用验证
if(saveIsValidationRequired){
scope.startExecValidations();
}
});
});
//})
}
};
}]);


UPDATE 1: the question will be enhanced based on the feedback from the comments.
UPDATE 2: Some progress has been made. Need additinoal help to get through. Please read below.
UPDATE 3: Bug fixing in provided sample code causing duplication in table rows when compiling the element using $compile(el[0])(scope);.

On page load, a list of field names is retrieved from Database which indicates what fields are required using ajax call getRequiredFieldInfo(). This call must be completed successfully before executing the related angular code under the directive check-if-required to manipulate the required attribute. This directive must loop over all input fields and mark them as required based on the list which is retrieved from the Database.

I did some research and found this post which seems to be the closest to my requirements:

https://stackoverflow.com/a/28207652/4180447

and finally found a working jsfiddle version here (updated):

http://jsfiddle.net/tarekahf/d50tr99u/

I can use the following simple approach:

<input name="firstName" type="text" foo ng-required="isFieldRequired('firstName')" />

The function isFieldRequired() will check if the passed field name is found in the list, it will return true.

The problem with this approach is that I have to add this function to each and every field which might be required.

Also, will have to pass the field name each time. To be more efficient, I will have to use a directive on the parent element div or fieldset which will allow me to access all child elements, and process the required attributes for the all the input elements.

This directive need to be changed as follows:

  • To be added to the parent element of the group of fields whose required attribute will be processed and modified if needed.

  • Compare the element name against the list of fields to set as required and apply the change accordingly.

The updated code (as I am researching the solution):

STYLE

input.ng-invalid, li.ng-invalid {
    background:#F84072;
    border: 2px red solid;
}

HTML - NAVIGATION TABS:

<ul  class="nav nav-pills">
    <li ng-class="{'ng-invalid':mainForm.homeForm.$invalid && mainPromiseResolved}" class="active"><a data-toggle="pill" href="#home"><%=homeTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.clientForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu1"><%=clientTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.appraiserForm.$invalid && mainPromiseResolved}"> <a data-toggle="pill" href="#menu2"><%=appraiserTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.propertyForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu3"><%=propertyTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.serviceForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu4"><%=servicesTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.constructionStage.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu5"><%=constructionStageTabName%></a></li>    
    <li ng-class="{'ng-invalid':mainForm.costForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu6"><%=costTabName%></a></li>  
    <li ng-class="{'ng-invalid':mainForm.certificationForm.$invalid && mainPromiseResolved}" ng-click="redrawCanvas()"><a data-toggle="pill" href="#menu7"><%=certificationTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.photosForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu8"><%=photoTabName%></a></li>
    <li ng-class="{'ng-invalid':mainForm.mapForm.$invalid && mainPromiseResolved}"><a data-toggle="pill" href="#menu9"><%=locationTabName%></a></li>    
</ul>

HTML - Form

<div id="menu2" class="tab-pane fade" ng-form="appraiserForm">
    <fieldset ng-disabled="isAppraiserSigned()" check-if-required>
        <input type="text" id="appraiser_name" name="appraiser_name" ng-model="sigRoles.appraiser.roleNameModel" style="width: 536px; ">
        <input type="text" id="appraiser_company" style="width: 536px; ">
        ... 
        ... 
    </fieldset>
</div>

Javascrip:

app.controller('formMainController', ['$scope', '$timeout', '$q', function($scope, $timeout, $q) {

    $scope.runProcessAndInit = function () {
        var q = $q.defer();     //Create a promise controller
        angular.element(document).ready(function(){
            //perform all client updates here
            q.resolve('success');   //notify execution is completed successfully - inside document 'ready' event.
        })
    return q.promise;   //return the promise object.
    }
    //mainPromiseResolved is used to indicate all ajax calls and client updates are done.
    $scope.mainPromiseResolved = false;
    $scope.mainPromise = $scope.runProcessAndInit();
    $scope.mainPromise.then(function(success) {
        //debugger;
        $scope.$broadcast('event:force-model-update');
        //mainPromiseResolved is mainly used in angular validation to prevent showing errors until all client updates are done.
        $scope.mainPromiseResolved = true;
        return 'main promise done';
    })
    $scope.isFieldRequired = function (prmFieldName) {
        var isFound = false;
        var oRequiredField = formView.getRequiredField();
        findField: {
            for(var subformName in oRequiredField) {
                isFound = prmFieldName in oRequiredField[subformName];
                if (isFound) {
                    break findField;
                }
            }
        }
        return isFound;
    }    
    function getRequiredFieldInfo() {
        var q = $q.defer();
        var appUrl = getAppURL();   
        $.get(appUrl + "/servlet/..."
                    + "&timestamp="     + new Date().getTime(), 
                    function(data, status){
            //console.log("json fields:" + data);           
            var obj = JSON.parse(data);
            formView.setRequiredField(obj);
            q.resolve('success');
            // console.log(JSON.stringify(formView.getRequiredField()));            
        });
        return q.promise;
    }
    $scope.requiredFieldsPromise = getRequiredFieldInfo(); 
}]);

app.directive('checkIfRequired', ['$compile', function ($compile) {
    return {
        require: '?ngModel',
        link: function (scope, el, attrs, ngModel) {
            if (!ngModel) {
                //return;
            }
            //debugger;
            var children = $(":input", el);
            angular.element(document).ready(function (){
                scope.requiredFieldsPromise.then(function(success) {
                    //remove the attribute to avoid recursive calls
                    el.removeAttr('check-if-required');
                    //Comment line below as it caused duplication in table raws, and I don't know why.
                    //$compile(el[0])(scope);
                    angular.forEach(children, function(value, key) {
                        //debugger;
                        if (scope.isFieldRequired(value.id)) {
                            angular.element(value).attr('required', true);
                            //el.removeAttr('check-if-required');
                            $compile(value)(scope);
                        }
                    });
                })
            })
        }
    };
}]); 

I've already made some progress. However, I still need more help. Following is the status:

  • Done: get required fields list from DB and then execute code in directive to manipulate the required attribute.
  • Done: Loop over the child input elements from a given angular element el which is passed to link function function (scope, el, attrs, ngModel).

  • Done: Add required attribute to each child element if isFieldRequired(fieldName) is true?

  • Done: Use promise to ensure all ajax DB calls and client updates are done before executing angular code.

  • How to recursively loop over the child elements if they are nested inside another ng-form subform or div element?

  • How to ensure that each element has ngModel object?

  • How to restrict the directive to div, fieldsset or similar elements?

Tarek

解决方案

The following code will satisfy the main requirement, in addition, for each element under the div block, it will allow adding attribute check-if-required-expr. This new attribute may be used to call a scope boolean expression to decide the required attribute in case the field is not found the list of required fields.

I was wondering if there is a way to use the standard ng-required directive instead of the custom attribute check-if-required-expr which basically does the same as ng-required. The only problem if I use ng-required is that it might override the logic of the required field if it was specified in the list.

So the question here: is there a way to find out if the required attribute is set, and if yes, then do not check the required expression, otherwise, execute the ng-required expression.

HTML

<div id='signature-pad' class="m-signature-pad break" ng-class="{'ng-invalid':certificationForm[theRoleData.signatureBase64].$invalid && mainPromiseResolved}" check-if-required>
...
    <div class="m-signature-pad--body">
        <canvas id="appraiser_signature_section" redraw ng-signature-pad="signature" ng-hide="isSigned()">
        </canvas>
        <img ng-src="{{signatureDataURL()}}" ng-hide="!isSigned()" load-signature-image>
        <input id="{{theRoleData.signatureBase64}}" name="{{theRoleData.signatureBase64}}" type="text" ng-hide="true" ng-model="signatureBase64" check-if-required-expr="sigDetailsAvail(theRoleData)" force-model-update/>
    </div>
...

</div>

Basically, in the above HTML, the input field which has check-if-required-expr, indicates that if this field is not found in the list of required fields then execute the expression to decide if the field is required.

JavaScript

//Define directive check-if-required
//This directive will loop over all child input elements and add the required attributes if needed
app.directive('checkIfRequired', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
    return {
        /*require: '?ngModel',*/
        require: '?^form',
        link: function (scope, el, attrs, ngForm) {
            /*if (!ngModel) {
                return;
            }*/
            var saveIsValidationRequired;
            var children;
            saveIsValidationRequired = scope.isValidationRequired;  //Save current flag value
            scope.stopExecValidations();
            el.removeAttr('check-if-required');
            $timeout(function() {
                //Get all input elements of the descendants of `el` 
                children = $(":input", el);
                //Run the following as early as possible but just wait (using promise) until 
                //  the list of required fields is retrieved from Database
                //scope.requiredFieldsPromise.then(function(success) {
                scope.requiredFieldsPromise.then(function(success) {
                    //The line below caused duplication of the table in construction stage, so it is removed and no impact
                    //$compile(el[0])(scope);
                    angular.forEach(children, function(child, key) {
                        var elmScope;
                        var elmModel;
                        try {
                            if(child && child.id) {
                                elmScope = angular.element(child).scope() || scope;
                                elmModel = angular.element(child).controller('ngModel');
                                if (ngForm && elmModel && ngForm[elmModel.$name]) {
                                    scope.$watch(function(){
                                        //Watch the errors for the defined field - convert to JSON string.
                                        return JSON.stringify(ngForm[elmModel.$name].$error);
                                    }, function (newValue, oldValue){
                                        //The validation error message will be placed on the element 'title' attribute which will be the field 'tooltip'. 
                                        var maxlength;
                                        var minlength;
                                        if (angular.isDefined(newValue)) {
                                            if (ngForm[elmModel.$name].$error.maxlength) {
                                                //If invalid, add the error message if number of entered characters is more than the defined maximum
                                                maxlength = scope.$eval(angular.element(child).attr('ng-maxlength'));
                                                child.title = ("Number of characters entered should not exceed '{0}' characters.").format(maxlength);
                                            } else {
                                                //Remove the error if valid.
                                                child.removeAttribute('title');
                                            }
                                        }
                                    });
                                }
                                if (scope.isFieldRequired(child.id)) {
                                    angular.element(child).attr('ng-required', "true");
                                    $compile(child)(elmScope);
                                }
                                //Check if the element is not in "Required" list, and it has an expression to control requried, then
                                //... add the attribute 'ng-required' with the expression specified to the element and compile.
                                if (!angular.element(child).prop('required') && child.attributes.hasOwnProperty("check-if-required-expr")) {
                                    var isRequiredExpr = child.attributes["check-if-required-expr"].child;
                                    angular.element(child).attr('ng-required', isRequiredExpr);
                                    $compile(child)(elmScope);
                                }
                                var validObjects = scope.getFieldValidation(child.id);
                                if (angular.isArray(validObjects)) {
                                    for (var idx=0; idx < validObjects.length; idx++) {
                                        var validObject = validObjects[idx];
                                        var test = validObject.test || "true"; //if not exist, it means the rule should always be applied
                                        var minLenExp = validObject.minlen;
                                        var maxLenExp = validObject.maxlen;
                                        var isRequiredExp = validObject.required || false;
                                        isRequiredExp = angular.isString(isRequiredExp)?isRequiredExp:isRequiredExp.toString();
                                        //scope.$evalAsync(function(){
                                            if (test && (minLenExp || maxLenExp || isRequiredExp)) {
                                                var testEval = scope.$eval(test, elmScope);
                                                if (testEval) {
                                                    if (minLenExp) {
                                                        angular.element(child).attr('ng-minlength', minLenExp);
                                                    }
                                                    if (maxLenExp) {
                                                        angular.element(child).attr('ng-maxlength', maxLenExp);
                                                    }
                                                    //If the "required" expression is '*skip*' then simply skip.
                                                    //If '*skip*' is used, this means the required validation is already defined in code
                                                    //and no need to replace it.
                                                    if (isRequiredExp && isRequiredExp != '*skip*') {
                                                        angular.element(child).attr('ng-required', isRequiredExp);
                                                    }
                                                    //Change how '$compile()' is used.
                                                    //      After reserach, found there is bug in Angular which is causing the fillowing issues when using '$compile()':
                                                    //      1. Duplicate values for drop-down list items.
                                                    //      2. Inteference with dateppciker Angular UI Bootstrap control
                                                    //      If this still happes, more research is needed to resolve this problem.
                                                    //      This is still work-in-progress. More research is needed.
                                                    //The compile statement below will be replaced ...
                                                    $compile(child)(elmScope, function (clone) {
                                                        angular.element(child).after(clone);     
                                                        angular.element(child).remove();
                                                    });
                                                    //Apply only the first matching validation rule
                                                    break;
                                                }
                                            }
                                    }
                                }
                            }
                        } catch (e) {
                            console.error("Error occuured in 'checkIfRequired' directive while applying validation logic on element ID '%s'. Error is: '%s'", child.id, e);
                        }
                    });
                    //If saved flag value is ture, enable validation
                    if (saveIsValidationRequired) {
                        scope.startExecValidations();
                    }
                });
            });
            //})
        }
    };
}]);

这篇关于角度动态要求对字段高亮的字段组进行验证,如果无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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