一尘不染

如何覆盖Angular对无效表单值的过滤,从而迫使Angular将$ viewValue持久化为$ modelValue?

angularjs

我需要能够暂时保留尚未完全验证的数据,然后在准备将其永久化时强制执行验证。但是Angular阻止了这一点。

我有一个表格。用户可以saveDraft()使用表单的早期版本,这些版本将保留在服务器上。然后,当用户准备就绪时,他们便可以使用submit()该表单,该表单将使用不同的标记来保留该表单,从而开始对该数据的实际处理。

我遇到的问题是Angular的内置验证。当用户将一些数据输入到带有验证的输入中时,该数据将缓存在$viewValue属性中。但是,如果验证失败,它将永远不会复制到该$modelValue属性,这是对$scope我将输入绑定到的实际属性的引用。因此,“无效”值将不会保留。

但是我们需要坚持下去。稍后,当用户commit()时,我们将迫使其纠正验证失败。此外,我们也没有办法知道用户是否会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优雅地更新它?和/或,是否有另一种更好的方法来获得相同的结果,从而有时我可以坚持进行验证,而有时可以坚持进行验证?

我正在考虑但不满意的其他选择:

  • 仅当用户点击submit()时,才手动运行验证。但这破坏了UI中即时内联验证的UX值。我们不妨将所有验证都卸载到服务器,然后每次都进行往返。
  • 制作ngModel和ngModelController的副本,并对其进行猴子补丁更新,$modelValue无论其有效性如何。但是,当应该有一条更优雅的道路时,这会破坏框架。

在此处查看CodePen

(旁注:Angular似乎正在根据验证器在 两个方向上
对数据进行过滤。如果在模型上为formData.zip设置默认值‘1234’,则该字符不足以验证字符,Angular不会这样做。甚至不显示它。它永远不会到达初始$viewValue。)


阅读 244

收藏
2020-07-04

共1个答案

一尘不染

从Angular 1.3版本开始,可以使用以下解决方案:

您可以ng-model-options="{ allowInvalid: true }"在模型的输入字段中设置要保留无效属性的位置。

allowInvalid:布尔值,指示可以使用未正确验证的值来设置模型,而不是将模型设置为未定义的默认行为

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

2020-07-04