在编辑表单的任何部分时强制验证AngularJS中的整个表单?

时间:2013-07-20 19:04:50

标签: angularjs

我有一个表单,其中有效性取决于多个文本框之间的关系。例如,如果有三个文本框,则仅当每个文本框的整数值大于上一个文本框的整数值时,该表单才有效。

我想设置此表单,以便在用户编辑任何文本框时,整个表单都会重新生效。

我尝试在所有文本框上设置ng-change = revalidate(),其中包含以下内容:

$scope.revalidate = function() {
    var formData = $parse('signals');
    var dataCopy = angular.copy(formData($scope));
    formData.assign($scope, dataCopy);
};

我希望复制和重新分配表单的数据会触发重新验证,但它似乎不起作用。我怎么做到这一点?

2 个答案:

答案 0 :(得分:0)

我通过创建指令解决了这个问题。在该指令中,我对所有文本框的连接值设置了$ watch。然后,当$ watch看到任何文本框中的更改时,它会重新验证该元素。由于此指令适用于我的所有文本框,因此在编辑任何一个文本框时,整个表单都会重新生效。

如果某人有比这更优雅的解决方案,请告诉我。

link: function(scope, elm, attrs, ctrl) {
                // when any of the intervals for this signal change, revalidate this interval
                scope.$watch(
                    // loop through all the intervals for this signal, concatenate their values into one string
                    function() {
                        var intervals = [],
                            child = scope.$parent.$$childHead;
                        while (child !== null) {
                            console.log(child);
                            intervals.push(child.interval.end);
                            child = child.$$nextSibling;
                        }
                        return intervals.join();
                    },
                    function() {
                        validate(ctrl.$viewValue);
                    }
                );

                function validate(intervalDateTimeFromView) {
                    var valid = false;
                    // if this interval ends before or at the same time as the previous interval
                    if (scope.$$prevSibling && Number(intervalDateTimeFromView) <= Number(scope.$$prevSibling.interval.end))
                    {
                        ctrl.$setValidity('overlappingInterval', false);
                        return undefined;
                    } else {
                        ctrl.$setValidity('overlappingInterval', true);
                        return intervalDateTimeFromView;
                    }


                }

                ctrl.$parsers.unshift(validate);
                ctrl.$formatters.unshift(validate);

            }

答案 1 :(得分:0)

它并不完美,但它正是我现在所做的工作:

$element.bind('blur', function() {
    formCtrl[inputName].$dirty = true;
    $scope.$emit('validate-refresh');
});

$scope.$on('validate-refresh', function() {
    var control = formCtrl[inputName];
    if (control.$dirty) {
        control.$setViewValue(control.$viewValue);
    }
}