我在填写表单时编写了一些自定义验证代码,但需要将$timeout
设置为>100毫秒才能使其工作,我很想知道原因。
所需的表单元素遵循此格式。如果输入错误,我会添加"novalidate"类:(注意,表单中有很多这样的元素)
<div class="dottedWrapper" ng-class="{novalidate:(newController.jobDescription.length == 0) && newController.formSubmitted}">
提交表单时,我会检查是否有任何元素具有"novalidate"类并返回。
self.formSubmitted = true;
$timeout(function () {
// Validate!
if (document.getElementsByClassName("novalidate").length > 0) {
return;
}
...
}, 100); // MUST SET AT LEAST 100ms for it to work in safari
然而,只有当我在Safari中将时间设置为100毫秒以上时,这才有效。在chrome中,只需要将其设置为1ms。
如果我错了,请纠正我,但这是我的想法,并表明我是一个角度新手:
我在开头设置了"
self.formSubmitted = true;
"。这导致通过双向数据绑定对所有div进行更新,因为"formSubmitted"包含在ng类中。这是通过摘要循环完成的,这意味着我不能在之后直接运行"
document.getElementsByClassName("novalidate")
",因为摘要循环大多只运行一次并更新所有内容。所以。。。我使用
$timeout
,认为它会让当前的摘要循环运行,然后跳到下一个摘要循环。此时,应更新所有元素。
您正在打破MVC模式。不要——这是不好的做法。
你为什么不直接做:
if (self.jobDescription.length == 0 && self.formSubmitted)
return;
除了Pixelbits的答案(我完全同意)之外,您可以尝试用以下选项之一替换$timeout;
$evalAsync
$$postDigest
前者将触发一个新的$digest循环(就像$timeout一样),而后者不会。
即便如此,我认为您最好利用内置的input
验证指令。不检查DOM中是否存在novalidate
类,只需检查<form>.$valid
属性即可(当给定name
属性时,<form>
会暴露在$scope上)。
你的观点会是这样的;
<form name="myForm">
<input ng-model="formData.jobDescription" ng-minlength="1">
</form>
然后在你的控制器中;
// var form = $scope.myForm;
console.log(form.$valid); // true|false
现在,上面的建议可能不适用于您的用例-我们需要看到更多您的实现,以便能够在更大程度上帮助您。