Класс ‘ng-invalid-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()для оценки выражения и установит требуемый атрибут соответственно.

См. изображение ниже Для больше деталей.

Все работает нормально. Единственная проблема заключается в том, что когда поле» Name «очищено, обязательный атрибут для поля» Member # » должен быть удален, а выделение должно быть очищено, однако класс ng-invalid-requiredвсе еще добавлен, и это вызывает выделение.

Вы можете видеть$error, что объект для NgModelControllerназванного super_aic_member_numberвычисляется правильно в соответствии с намеченной логикой.

Таким образом, в основном вопрос заключается в том, как обеспечить правильную синхронизацию стиля с изменением requiredатрибута?

Введите описание изображения здесь

1 ответ

  1. Наконец, мне удалось найти решение. Вместо того , чтобы использовать $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();
                    }
                })
                //})
            }
        };
    }]);