XML*_*XML 10 javascript forms validation html5 angularjs
我需要能够暂时保留尚未完全验证的数据,然后在我准备将其永久化时执行验证.但Angular正在阻止这一点.
我有一张表格.用户可以saveDraft()在表单的早期版本上保留到服务器.然后,当用户准备好时,他们可以submit()使用不同标志持久保存的表单,从而开始实际处理该数据.
我遇到的问题是使用Angular的内置验证.当用户将某些数据输入到带有验证的输入中时,该数据将缓存在$viewValue属性上.但是如果验证失败,它永远不会复制到$modelValue属性,这是对$scope我绑定输入的实际属性的引用.因此,"无效"值将不会持久存在.
但我们需要坚持下去.当他们提交()时,我们将处理强制用户以后更正其验证失败的问题.此外,我们也没有办法知道用户是否会saveDraft()或submit()在视图/控制器的特定实例,所以我们不能设置的意见和验证不同事前.
我的想法是,我们需要以某种方式迭代表单元素并让Angular以某种方式让数据通过.但我找不到一种灵活且可扩展的方式.
我已经尝试过设置$scope.formName.inputName.$modelValue = $scope.formName.inputName.$viewValue,但这似乎只会让众神感到不安,因为这两个值都是无效的.
我尝试过使用$scope.formName.inputName.$setValidity('', true),但这只会更新UI状态.它永远不会触及$modelValue.
我可以成功使用,$scope.model.boundPropertyName = $scope.formName.inputName.$viewValue但这感觉非常迫切,并且不允许boundPropertyName和的标识符之间存在任何差异inputName.换句话说,您需要为所有表单控件提供单独的函数,或者您需要依赖命名约定.两者都是超脆的.
那么......我怎样才能$modelValue更新优雅呢?和/或者,是否有另一种更好的方法来获得相同的结果,有时候我可以坚持验证,有时可以坚持下去?
我正在考虑的其他选择,但不满意:
$modelValue无论其有效性如何.但是当应该有更优雅的路径时,这会破坏框架.(侧注:Angular似乎是根据验证器在两个方向上过滤数据.如果你在模型上为'1234'的formData.zip设置了一个默认值,这个字符不足以验证,Angular不会'甚至展示它.它永远不会达到最初$viewValue.)
Ale*_*lis 19
从Angular 1.3版开始可以使用以下解决方案:
您可以ng-model-options="{ allowInvalid: true }"在模型的输入字段中设置要保留无效属性的位置.
allowInvalid:布尔值,表示可以使用未正确验证的值设置模型,而不是将模型设置为undefined的默认行为
https://docs.angularjs.org/api/ng/directive/ngModelOptions
然后,当您准备向用户显示其验证错误时,您可以自由地按照自己的方式进行操作.只需记住提供输入和表单name属性,以便在范围内引用它们.
例如 if($scope.myFormName.my_input_name.$invalid) { ... }
相关教程:http://blog.thoughtram.io/angularjs/2014/10/19/exploring-angular-1.3-ng-model-options.html
Emil van Galen有一篇博文,内容涵盖了这个问题.我已经使用了他的输入指令,它完美地运行.
正如他所指出的,NgModelController的$ parsers数组是:
每当控件从DOM读取值时,作为管道执行的函数数组.反过来,每个函数都被调用,将值传递给下一个函数.用于清理/转换值以及验证.对于验证,解析器应使用$ setValidity()更新有效性状态,并为无效值返回undefined.
因此,要允许将模型更新为无效值,同时保留验证结果,请创建不返回undefined无效值的指令.例如,Emil的指令将无效的,未定义的字符串值恢复为模型值,否则返回视图值:
angular.module('jdFixInvalidValueFormatting', [])
.directive('input', function() {
return {
require: '?ngModel',
restrict: 'E',
link: function($scope, $element, $attrs, ngModelController) {
var inputType = angular.lowercase($attrs.type);
if (!ngModelController || inputType === 'radio' ||
inputType === 'checkbox') {
return;
}
ngModelController.$formatters.unshift(function(value) {
if (ngModelController.$invalid && angular.isUndefined(value)
&& typeof ngModelController.$modelValue === 'string') {
return ngModelController.$modelValue;
} else {
return value;
}
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
你可以看到它在他的Plunker中工作(还要注意他对改进处理null而不是undefined):http://plnkr.co/edit/gist:6674554?p = preview
| 归档时间: |
|
| 查看次数: |
7132 次 |
| 最近记录: |