在AngularJS中使用依赖字段进行表单验证

时间:2022-06-11 20:40:17

I have an object that has 2 fields, while 1 should be less than or equal to another.

我有一个有2个字段的对象,而1应该小于或等于另一个。

Say it's HDD quota settings and I need the threshold to be less than or equal to HDD's size.

说它是硬盘配额设置,我需要阈值小于或等于硬盘的大小。

I am trying to use angular's ui-utils#validate.

我正在尝试使用angular的ui-utils #validify。

This is how I got so far: http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview (i hope the link will work)

这就是我到目前为止的方法:http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview(我希望链接能够正常工作)

The problem that I am having is that it works to one direction:

我遇到的问题是它适用于一个方向:

Setting size and then playing with threshold works ok

设置大小然后玩阈值工作正常

But if I try to change size, after threshold is in invalid state - nothing happens. This is because invalid threshold is not set on the model and size id being compared against null or undefined (or something like that).

但是如果我尝试改变大小,在阈值处于无效状态之后 - 没有任何反应。这是因为未在模型上设置无效阈值,并且将大小id与null或未定义(或类似的东西)进行比较。

On one hand I understand the logic of not setting invalid value on the model... but here it is getting in my way.

一方面,我理解不在模型上设置无效值的逻辑......但是在这里它正在妨碍我。

So, any help making this work will be appreciated.

所以,任何帮助做这项工作将不胜感激。

2 个解决方案

#1


6  

I have played with custom directives and cooked something that works for my case.

我玩过自定义指令并烹饪了适用于我的情况的东西。

On my input for threshold I have less-than-or-equal="quota.size" directive, passing it the model's property to validate against (I want quota.threshold to be less than or equal to quota.size):

在我输入阈值时,我有一个小于或等于=“quota.size”指令,传递模型的属性以进行验证(我希望quota.threshold小于或等于quota.size):

<input type="number" name="threshold" 
    ng-model="quota.threshold" 
    required 
    less-than-or-equal="quota.size" />

In link function of lessThanOrEqual directive it starts to watch the quota.size and when quota.size changes it just tries to set the current view value of threshold on model:

在lessThanOrEqual指令的link函数中,它开始监视quota.size,当quota.size更改时,它只是尝试在模型上设置阈值的当前视图值:

link: (scope, elem, attr, ctrl) ->
    scope.$watch attr.lessThanOrEqual, (newValue) ->
        ctrl.$setViewValue(ctrl.$viewValue)

Then there is the parser that does the validation by calling scope.thresholdValidate(thresholdValue) method passing it the candidate value. This method returns true if validation succeeded and if it does - it returns the new value, otherwise - current model's value:

然后是解析器通过调用scope.thresholdValidate(thresholdValue)方法来传递候选值。如果验证成功,则此方法返回true,如果确实成功,则返回新值,否则返回当前模型的值:

    ctrl.$parsers.push (viewValue) ->
        newValue = ctrl.$modelValue
        if not scope.thresholdValidate viewValue    
            ctrl.$setValidity('lessThanOrEqual', false)
        else
            ctrl.$setValidity('lessThanOrEqual', true)
            newValue = viewValue
        newValue

I am pushing the parser to parser collection, as opposite to unshifting it like most of the examples suggest, because I want angular to validate required and number directives, so I get here only if I have a valid and parsed number (less work for me, but for text inputs I probably should do the parsing job)

我正在将解析器推送到解析器集合,与大多数示例建议的解除对象一样,因为我想要angular来验证必需和数字指令,所以我只有在我有一个有效且解析的数字时才会到达这里(对我来说工作量少) ,但对于文本输入我可能应该做解析工作)

Here is my playground: http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview

这是我的游乐场:http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview

#2


3  

Better late than never, you need to add ng-model-options="{allowInvalid:true}" to your form input elements to stop this happening - the problem is that when a promise is rejected (e.g. using $q or $http) the model, by default, is not updated. Crazy huh! Cost me a day working this out.

迟到总比你好,你需要在你的表单输入元素中添加ng-model-options =“{allowInvalid:true}”来阻止这种情况发生 - 问题是当一个promise被拒绝时(例如使用$ q或$ http)默认情况下,模型不会更新。疯了吧!我花了一天时间来完成这项工作。

I have written a plunkr specifically for this problem - Trust me this code is good ... http://embed.plnkr.co/xICScojgmcMkghMaYSsJ/preview

我专门针对这个问题编写了一个plunkr - 相信我这个代码很好... http://embed.plnkr.co/xICScojgmcMkghMaYSsJ/preview

#1


6  

I have played with custom directives and cooked something that works for my case.

我玩过自定义指令并烹饪了适用于我的情况的东西。

On my input for threshold I have less-than-or-equal="quota.size" directive, passing it the model's property to validate against (I want quota.threshold to be less than or equal to quota.size):

在我输入阈值时,我有一个小于或等于=“quota.size”指令,传递模型的属性以进行验证(我希望quota.threshold小于或等于quota.size):

<input type="number" name="threshold" 
    ng-model="quota.threshold" 
    required 
    less-than-or-equal="quota.size" />

In link function of lessThanOrEqual directive it starts to watch the quota.size and when quota.size changes it just tries to set the current view value of threshold on model:

在lessThanOrEqual指令的link函数中,它开始监视quota.size,当quota.size更改时,它只是尝试在模型上设置阈值的当前视图值:

link: (scope, elem, attr, ctrl) ->
    scope.$watch attr.lessThanOrEqual, (newValue) ->
        ctrl.$setViewValue(ctrl.$viewValue)

Then there is the parser that does the validation by calling scope.thresholdValidate(thresholdValue) method passing it the candidate value. This method returns true if validation succeeded and if it does - it returns the new value, otherwise - current model's value:

然后是解析器通过调用scope.thresholdValidate(thresholdValue)方法来传递候选值。如果验证成功,则此方法返回true,如果确实成功,则返回新值,否则返回当前模型的值:

    ctrl.$parsers.push (viewValue) ->
        newValue = ctrl.$modelValue
        if not scope.thresholdValidate viewValue    
            ctrl.$setValidity('lessThanOrEqual', false)
        else
            ctrl.$setValidity('lessThanOrEqual', true)
            newValue = viewValue
        newValue

I am pushing the parser to parser collection, as opposite to unshifting it like most of the examples suggest, because I want angular to validate required and number directives, so I get here only if I have a valid and parsed number (less work for me, but for text inputs I probably should do the parsing job)

我正在将解析器推送到解析器集合,与大多数示例建议的解除对象一样,因为我想要angular来验证必需和数字指令,所以我只有在我有一个有效且解析的数字时才会到达这里(对我来说工作量少) ,但对于文本输入我可能应该做解析工作)

Here is my playground: http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview

这是我的游乐场:http://embed.plnkr.co/EysaRdu2vuuyXAXJcJmE/preview

#2


3  

Better late than never, you need to add ng-model-options="{allowInvalid:true}" to your form input elements to stop this happening - the problem is that when a promise is rejected (e.g. using $q or $http) the model, by default, is not updated. Crazy huh! Cost me a day working this out.

迟到总比你好,你需要在你的表单输入元素中添加ng-model-options =“{allowInvalid:true}”来阻止这种情况发生 - 问题是当一个promise被拒绝时(例如使用$ q或$ http)默认情况下,模型不会更新。疯了吧!我花了一天时间来完成这项工作。

I have written a plunkr specifically for this problem - Trust me this code is good ... http://embed.plnkr.co/xICScojgmcMkghMaYSsJ/preview

我专门针对这个问题编写了一个plunkr - 相信我这个代码很好... http://embed.plnkr.co/xICScojgmcMkghMaYSsJ/preview

相关文章