使用JavaScript函数进行AngularJS表单/字段验证,无需指令

10

如何在Angular中验证一个字段,而不使用指令?例如:我想对输入字段进行以下验证:

  • 如果字段为空,我们应该显示“字段必须包含值”消息。
  • 如果字段包含字母数字字符,我们应该显示“字段只能包含数字”消息。
  • 偶数-向用户显示消息“值必须是偶数”。

我想在调用JavaScript函数时进行以下验证。

我在Google上搜索并看到有一种使用ng-valid和$error的方法,但是我无法使其工作。

下面的代码是根据我得到的答案之一编写的:

<div ng-app>
<form name='theForm' novalidate>
    <input type='text' name='theText' ng-model='theText' ng-pattern='/^[0-9]+$/'/>
    <span ng-show='theForm.theText.$error.pattern'>Field can contain only digits</span>
    <span ng-show='theText.length<1'>Field must contain a value</span>
    <span ng-show='theText%2!=0&&document.getElementsByName("theText").value!=""&&!theForm.theText.$error.pattern&&!theForm.theText.$pristine'>Value must be an even number</span>
    <br/><input type='submit' value='Submit' />
</form>

我希望将上一个 [span] 标签的内容放到 JavaScript 函数中,以使其更通用,并在条件改变时仅更改 JS 而不更改 HTML。

请问有人可以提供建议吗?最好附带一个可行的示例。


如果你想在JavaScript函数中执行所有这些验证,为什么不采用Angular的方式并创建一个自定义验证指令呢? - Shay Friedman
为什么要使用JavaScript函数?Angular可以像这里一样监视模型:http://jsfiddle.net/DotDotDot/6UJZk/1/,使用另一个函数可能不如此高效。 - DotDotDot
4个回答

23

我很惊讶没有人提到ui-validate

$scope.isOdd = function($value){
  return $value % 2;
}
...
<form name="myform">
  <input ng-model="myVal" name="value" required
    ng-pattern="/^[0-9]*$/" ui-validate=" 'isOdd($value)' "></input>
  <pre>{{myform.value.$error|json}}</pre>
</form>

这就是最简单的方式,同时也是正确的AngularJS验证方式(不是愚蠢的watch方法)

这里有一个工作示例


1
这正是我所需要的,谢谢。 请问您能否添加一个可运行的示例?我无法使您的示例工作。 - Scription
1
@Scription已添加。看起来这个愚蠢的东西需要一个表单才能工作。不要忘记ui.validate模块。 - ProLoser

3
我知道这个问题很老了,我也知道你不想用指令,但你可能会考虑使用指令,如果它是“Angular”的方式...好吧,这是我的Angular-Validation。 我在Github上做了一个项目,我认为它比任何可用的东西都好......我以优秀的Laravel PHP框架为基础,在Angular下提供它......它非常简单,你只需要两行 一行代码、一行输入,一行错误显示,就这样了......从此不再多谈,让我们来举些例子:
<!-- example 1 -->
<label for="input1">Email</label>
<input type="text" validation="email|min_len:3|max_len:25|required" ng-model="form1.input1" name="input1" />

<!-- example 2 -->
<label for="input2">Alphanumeric + Exact(3) + required</label>
<input type="text" validation="alpha|exact_len:3|required" ng-model="form1.input2" name="input2" />

所以,我可以在一个简单的指令validation="min_len:2|max_len:10|required|integer"中定义任意数量的验证规则(已有25种以上的验证器),错误消息将始终显示在下一个<span>中。你们喜欢这个想法吗?只需一行代码即可输入,一行代码即可显示错误信息,再也没有比这更简单的了...哦,如果您想添加自定义正则表达式,我甚至还支持它。另外一个好处是,我还支持任何您想要的触发事件,最常见的可能是onbluronkeyup。哦,我还通过JSON外部文件支持多种本地化语言。我真的把我想到的所有功能都加入到了一个疯狂简单的指令中。

不再需要为一个输入框编写10行代码的混乱表单(对不起,但我总觉得那有点过分),即使对于一个带有5个验证器的输入框,您只需要两行代码就可以搞定。而且,不用担心表单无效,我已经处理好了,这都是“Angular”的好方法。

请查看我的Github项目Angular-Validation……我相信你会喜欢的=)

更新
另一个惊喜奖励!为了使用户体验更加流畅,我添加了计时器验证。这个概念很简单,不要在用户输入时打扰他,但如果他暂停或更改输入(onBlur),则进行验证……你喜欢吗?
您甚至可以按照自己的喜好自定义计时器,我已经在指令中将其默认为1秒,但如果您想自定义,您可以调用例如typing-limit="5000"来设置5秒超时。完整示例:

<input type="text" ng-model="form1.input1" typing-limit="5000" validation="integer|required" name="input1" />
<span class="validation text-danger"></span>


更新 #2
还添加了输入匹配确认验证(例如:密码确认),这里是示例代码。

<!-- input match confirmation, as for example: password confirmation -->
<label for="input4">Password</label>
<input type="password" name="input4" ng-model="form1.input4" validation="alpha|min_len:4|required"  />
<label for="input4c">Password Confirmation</label>
<input type="password" name="input4c" ng-model="form1.input4c" validation="match:form1.input4,Password|required"  />

更新 #3
重构指令,使得不需要使用<span>来显示错误信息,指令现在可以自主处理错误信息的显示,详见上方代码更改。

演示
Plunker中添加了实时演示。


感谢您的努力和插件。 - Scription
不客气,希望有很多人会使用它并帮助我改进它...请注意,我今天修复了一个错误,这可能是在你尝试之后发生的,请确保你使用最新的代码...谢谢...我很好奇,你会使用它吗?你喜欢这个概念吗? - ghiscoding
@ghiscoding 我很好奇,你为什么觉得这种方法比使用<input ng-pattern min max>更好?我认为你的项目演示中展示的所有用例都可以通过这三个属性来实现。 - ProLoser
1
@ProLoser.. 因为它非常简单,你的代码变得更短,而且你甚至不需要编写错误消息,指令会为你自动完成。现在我刚刚完成了一个糖果奖励,为了让用户体验更流畅,我只在用户不活动后进行验证。爱它 =) - ghiscoding

3
请看AngularJS表单文档:http://docs.angularjs.org/guide/forms。通常,它基于HTML5属性,例如:required、min、max等。
例如,要实现第一个需求——“空字段应显示“字段必须包含值”消息”,您可以这样做:
<input type="text" ng-model="user.name" name="uName" required /><br />
<div ng-show="form.uName.$invalid">
  <span ng-show="form.uName.$error.required">Field must contain a value.</span>
</div>

对于只包含数字的字段,您可以使用具有匹配正则表达式(例如:http://www.wufoo.com/html5/attributes/10-pattern.html)的pattern属性进行验证。
至于偶数验证,我不确定 - 我认为您需要进行自定义验证(意味着您必须创建一个指令)或以某种方式使用pattern属性。
最后但并非最不重要的一点是 - 记得在<form>标记中添加novalidate。否则,浏览器也会尝试验证您的字段,而您不想这样。
<form ... novalidate>
 ...
</form>

你只回答了我关于“require”属性的问题。 至于其他方面,也许我没有表达清楚,我想使用JavaScript函数,在每次用户按键输入到字段时进行正确的验证(或离开该字段)。 - Scription
我写了关于数字和偶数验证应该做什么的内容 - 对于数字,您可以使用模式属性(无需自定义JS函数)。对于偶数验证,那就比较棘手了,我认为您不可能没有指令。 - Shay Friedman
我不想使用任何指令,只用JS。 - Scription
3
如果你不想使用AngularJS的功能,为什么要使用它呢? - Shay Friedman

2

你可以尝试创建一个函数。

<span ng-show='isEven(theText)'>Value must be an even number</span>

$scope.isEven=function(data) {
    if(data) {
        return data%2===0
    }
    return true;
}

这种方法可以在当前控制器作用域或$rootScope上定义。

虽然指令可能更好,但这并不是非常Angular的方式,我认为它会起作用。


我想使用JavaScript并能够更改它,而不是更改HTML。然而,如果指令是“Angular”的方式,那么我也愿意考虑它。您能否给我一个在指令中使用它的示例? - Scription
如果您查看Angular开发人员指南中的表单部分,并检查“自定义验证”部分,您会在那里看到一个工作示例http://docs.angularjs.org/guide/forms - Chandermani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接