“ng-invalid-required”类已正确添加,但在删除时未删除

时间:2017-01-16 19:35:24

标签: angularjs styles required

我使用$watch()使用以下自定义指令控制required属性:

app.directive('checkIfRequired', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
    return {
        /*require: '?ngModel',*/
        link: function (scope, el, attrs, ngModel) {
            var children = $(":input", el);
            var saveIsValidationRequired;
            //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) {
                //If needed, stop validation while adding required attribute
                saveIsValidationRequired = scope.isValidationRequired;  //Save current flag value
                scope.stopExecValidations();
                //remove the attribute `check-if-required` to avoid recursive calls
                el.removeAttr('check-if-required');
                angular.forEach(children, function(value, key) {
                    if (scope.isFieldRequired(value.id)) {
                        angular.element(value).attr('required', true);
                        $compile(value)(scope);
                    }
                    //Check if the element is not in "Required" list, and it has a function to control requried, then
                    //... execute the function using $watch and $parse and add the required attribute accordingly 
                    if (!angular.element(value).prop('required') && value.attributes.hasOwnProperty("check-if-required-expr")) {
                        var isRequiredExpr = value.attributes["check-if-required-expr"].value;
                        scope.$watch(function (){
                                var exprValue = $parse(isRequiredExpr)(scope);
                                return exprValue;
                            }
                            , function (oldValue, newValue){
                                var isRequired = $parse(isRequiredExpr)(scope);
                                if (isRequired) {
                                    angular.element(value).prop('required', true);
                                    $compile(value)(scope);
                                } else {
                                    angular.element(value).prop('required', false);
                                    $compile(value)(scope);
                                }
                                var elModel = angular.element(value).controller("ngModel");
                                elModel.$setViewValue(elModel.$viewValue);
                            })
                    }
                });
                //If saved flag value is true, enable validation
                if (saveIsValidationRequired) {
                    scope.startExecValidations();
                }
            })
            //})
        }
    };
}]);

基本上,上面的指令检查是否需要子元素,然后它将使用$compile(value)(scope)添加所需的属性,否则,它将检查是否指定了check-if-required-expr表达式,如果是的,它将使用$watch()来计算表达式,并相应地设置所需的属性。

有关详细信息,请参见下图。

一切正常。唯一的问题是,当清除“名称”字段时,应删除“成员#”字段的必需属性,并应清除突出显示,但仍会添加类ng-invalid-required,这会导致最重要的是。

您可以看到$error名为NgModelController的{​​{1}}对象按照预期的逻辑正确计算。

所以基本上这里的问题是如何确保样式与super_aic_member_number属性的更改正确同步?

enter image description here

1 个答案:

答案 0 :(得分:0)

最后,我设法找到了解决方案。我只是将这个表达式添加到$watch()属性,而不是使用check-if-required-expr监视表达式ng-required,然后,我将编译。

到目前为止,它工作正常。

以下是更新后的代码:

app.directive('checkIfRequired', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
    return {
        /*require: '?ngModel',*/
        link: function (scope, el, attrs, ngModel) {
            /*if (!ngModel) {
                return;
            }*/
            //debugger;
            var children = $(":input", el);
            var saveIsValidationRequired;
            //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) {
                //If needed, stop validation while adding required attribute
                saveIsValidationRequired = scope.isValidationRequired;  //Save current flag value
                scope.stopExecValidations();
                //remove the attribute `check-if-required` to avoid recursive calls
                el.removeAttr('check-if-required');
                angular.forEach(children, function(value, key) {
                    //debugger;  && (value.id != "pi_subject_namex" && value.id != "pi_subj_provincex")
                    if (scope.isFieldRequired(value.id)) {
                        angular.element(value).attr('required', true);
                        //el.removeAttr('check-if-required');
                        $compile(value)(scope);
                    }
                    //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(value).prop('required') && value.attributes.hasOwnProperty("check-if-required-expr")) {
                        var isRequiredExpr = value.attributes["check-if-required-expr"].value;
                        angular.element(value).attr('ng-required', isRequiredExpr);
                        $compile(value)(scope);
                    }
                });
                //If saved flag value is ture, enable validation
                if (saveIsValidationRequired) {
                    scope.startExecValidations();
                }
            })
            //})
        }
    };
}]);