使用带有Breeze的Angular验证指令阻止任何无效的输入

时间:2014-03-27 17:04:32

标签: javascript angularjs validation angularjs-directive breeze

如果将任何用于验证的角度指令(ng-minlength,ng-maxlength,ng-pattern等)添加到绑定到breeze实体的输入,则会阻止任何用户输入(如果发现无效)。

如果来自ng-model的值最初有效则会显示,但如果将值更改为无效,则清除输入字段,模型将设置为null,并且您无法输入任何可能最初的内容无效。但是,如果将有效值复制到它显示的字段中。

如果模型值在无效时清除输入然后阻止更改,则无效时将模型值设置为null。

此外,我有一种感觉,无论是什么导致这个问题也搞乱了ui-mask。没有角度验证指令就会发生同样的事情。

这是我从一个类似的问题中发现的一个Plunker,我修改过以显示我的问题: http://plnkr.co/edit/dVsF7GFY65a30soLL5W8?p=preview


修改

经过多个小时的研究后,我找到了一个有效的解决方案,虽然我不确定是否有任何副作用。

它首先通过将$ modelValue设置为'undefined',如果它失败了任何验证器,因为它通过$ parsers和$ formatters来实现验证。

我在Angular(第16331行)中发现了这个代码,每个角度验证器都会调用它:

function validate(ctrl, validatorName, validity, value){
  ctrl.$setValidity(validatorName, validity);
  return validity ? value : undefined;
}

我将其更改为返回'value'而不是'undefined':

function validate(ctrl, validatorName, validity, value){
      ctrl.$setValidity(validatorName, validity);

      return value;
    }

Angular仍然可以正确设置验证。虽然我确信这不是最好的解决方案,也不是一个好的解决方案。

我怀疑当Angular将$ modelValue设置为'undefined'时会出现问题,然后Breeze看到模型已更改并更新实体,然后更新模型然后清除输入等等......或类似的东西。 ..

我发现这对我的任务很有帮助。也许对你们中的一位比https://github.com/angular/angular.js/issues/1412

更了解的人会有所帮助

4 个答案:

答案 0 :(得分:3)

Angular 1.3.0-rc.1引入了allowInvalid选项,用于ngModelOptions指令。它本质上是OP在16331行的正式化。该选项指示Angular允许将无效的表单输入写入$ scope,并巧妙地解决问题。

用法:

<input type="email" ng-model-options="{allowInvalid: true}" ng-model="my_breeze_model.email"/>

有关详细信息,请参阅此功能请求:https://github.com/angular/angular.js/issues/8290

答案 1 :(得分:0)

我很高兴看到你的羽毛球员,看看Breeze能否做些什么。

我并不感到非常惊讶。我记得,当你将它与HTML 5验证结合起来时,Ng也会遇到困难。你真的应该只使用我认为的一种方案。

你不同意吗?

另外,您是否考虑过Breeze Labs breeze.directives.js中的zValidate指令?我们认为这是在视图中公开Breeze实体属性验证错误的最佳方式。

答案 2 :(得分:0)

要考虑的另一个解决方案是使用Angular 1.3 +提供的ng-model-options属性。

通过这种方式,您可以防止在每次按键后发生角度摘要,而是将其推迟到例如“模糊”事件,以便使用者有机会实际输入有效数据。

看起来像这样:

<input type="email" ng-model="customer.email" ng-model-options="{ updateOn: 'blur' }">

但是,这仍然有一个限制,即如果输入无效输入,在模糊时输入将被清除,使用必须再次输入。在我看来,用户不太友好,所以我将尝试用微风来解决这个问题。

但是,我认为这个解决方案也值得一提。

答案 3 :(得分:0)

https://docs.angularjs.org/error/ngModel/numfmt描述了如果程序模型更改不尊重输入的验证规则,Angular会将其视为编程错误,而不是用户输入错误。

  

如果您的模型不包含实际数字,则由应用程序开发人员使用将在ngModel $ formatters和$ parsers管道中进行转换的指令。

他们的示例描述了String的{​​{1}}模型值,但我认为这里适用相同的逻辑。如果您的输入包含minLength属性,则不应使用太短的字符串更新范围。

要解决此问题,请在输入中添加自定义指令,将自定义解析器推送到<input type='number'>管道。

例如,以下指令将阻止将$parsers的值写入范围,直到输入足够长的字符串为止:

<input type='text' minLength='4' min4>

这可以防止在Breeze将更新的值写回范围并最终覆盖输入中尚未合法的状态时发生的令人讨厌的交互。

请参阅Plunker demo