Javascript 在angularjs中,当模型数据在表单之外更改时,如何在观察者内正确检查表单有效性?
我对AngularJS还是一个新手,我想我很难理解$scope的时间安排。在控制器中,我为绑定到各种表单元素的一些模型数据设置了一个监视程序。当数据发生变化时,观察者会发出ajax请求,除非表单无效。我正在用我的表格检查表格的有效性。$valid。但是,这是非常简单的,除非在控制器中更新模型数据,而不是表单中。验证按预期运行,但form.$valid仍具有以前的值,而不是更新数据时的值。例如,如果表单以前是有效的,那么我删除绑定到所需输入的模型值,监视程序将触发,因为模型数据已更改,但当我记录myForm的值时,$valid它的值仍然为true,即使它应该为false 所以我的问题是A。为什么会发生这种情况?但更重要的是B。什么是正确的方式来处理我试图完成的事情?自定义指令有意义吗 这里是一个简化的例子 HTML:Javascript 在angularjs中,当模型数据在表单之外更改时,如何在观察者内正确检查表单有效性?,javascript,validation,angularjs,angularjs-scope,angularjs-ng-form,Javascript,Validation,Angularjs,Angularjs Scope,Angularjs Ng Form,我对AngularJS还是一个新手,我想我很难理解$scope的时间安排。在控制器中,我为绑定到各种表单元素的一些模型数据设置了一个监视程序。当数据发生变化时,观察者会发出ajax请求,除非表单无效。我正在用我的表格检查表格的有效性。$valid。但是,这是非常简单的,除非在控制器中更新模型数据,而不是表单中。验证按预期运行,但form.$valid仍具有以前的值,而不是更新数据时的值。例如,如果表单以前是有效的,那么我删除绑定到所需输入的模型值,监视程序将触发,因为模型数据已更改,但当我记录m
Fiddle:自定义指令是正确的选择。出于几个原因,通常建议将手表放在指令和控制器中。从高层次上讲,一个原因是控制器很薄,只能作为视图和服务之间的粘合剂进行操作。但你找到了一个特别有趣的原因 控制器在链接角度指令之前运行。因此,在Angular的
ngModelWatch()
对myData
执行之前,您的控制器手表会被添加到手表列表中ngModelWatch()
是Angular运行的地方(回想一下,$formatters
是在模型发生更改时触发验证的地方)
由于手表是按照添加到手表列表的顺序执行的,因此您的控制器$watch
在验证之前执行$formatters
如果将相同的$watch
放在指令中,则在将ngModelWatch()
添加到监视列表后,将在链接期间添加该指令。因此,指令的$watch
将在验证完成后执行
在这里,您可以查看
$formatters
和每个$watch
的执行顺序。您将看到指令版本按预期工作-在$formatters
之后运行似乎正常。这与您期望的相符吗?将手表放在$valid
本身是您的选择吗?像这样:嗯,小提琴肯定能用。在我的应用程序中,我有一个更复杂的嵌套表单设置,我想知道这是否与此有关。观看$valid可能是一个选项,理想情况下,我希望能够观察模型数据并理解为什么$valid在观察程序中没有返回正确的值。似乎在这种嵌套形式下也能工作:感谢您的清晰解释和更新的fiddle!这正是我想要的。
<div ng-controller="MyCtrl">
<form name="myForm">
<input type="text" name="myField" ng-model="myData" required>
<button type="button" ng-click="myData=''">Delete</button>
</form>
<div>
The watcher says the form is: <strong>{{ formStatus }}</strong>
</div>
</div>
myApp.controller('MyCtrl', ['$scope', function($scope) {
$scope.myData = 'abc';
$scope.formStatus = '';
$scope.$watch('myData', function(newVal, oldVal) {
if (newVal != oldVal) {
console.log("my data changed");
console.log("my form valid = ", $scope.myForm.$valid);
$scope.formStatus = $scope.myForm.$valid ? 'Valid' : 'Invalid';
}
});
}]);