3

我有一种形式,其有效性取决于多个文本框之间的关系。例如,如果有三个文本框,那么只有当每个文本框的整数值大于前一个文本框的整数值时,表单才有效。

我想设置这个表单,这样如果用户编辑任何文本框,整个表单都会重新验证。

我尝试在所有文本框上设置 ng-change=revalidate() ,如下所示:

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

我希望复制和重新分配表单的数据会触发重新验证,但它似乎不起作用。我将如何实现这一目标?

4

2 回答 2

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);
    }
}
于 2014-12-04T02:50:54.607 回答
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);

            }
于 2013-07-21T07:53:02.793 回答