Javascript 角度:复选框组';的验证与模型不同步
该复选框组要求至少选中一个复选框,以便启用“提交”按钮。Javascript 角度:复选框组';的验证与模型不同步,javascript,angularjs,angularjs-scope,angularjs-validation,angularjs-digest,Javascript,Angularjs,Angularjs Scope,Angularjs Validation,Angularjs Digest,该复选框组要求至少选中一个复选框,以便启用“提交”按钮。 取消选中所有复选框将禁用该按钮。 所有复选框都使用相同的范围属性(showRequired)将其标记为所需 发生的情况是,第一次单击并没有像应该的那样启用按钮。选择和取消选择其他复选框会使整个事情变得不正常;无论复选框处于何种状态,在任何给定的单击中都可能启用或不启用该按钮 令人不安的是,我看到类ng valid并不总是应用于所有复选框。有时它在一个复选框上,有时它在所有复选框上,或者它们的一些组合上。使用$timeout可以修复所有问题
取消选中所有复选框将禁用该按钮。
所有复选框都使用相同的范围属性(showRequired)将其标记为所需 发生的情况是,第一次单击并没有像应该的那样启用按钮。选择和取消选择其他复选框会使整个事情变得不正常;无论复选框处于何种状态,在任何给定的单击中都可能启用或不启用该按钮 令人不安的是,我看到类ng valid并不总是应用于所有复选框。有时它在一个复选框上,有时它在所有复选框上,或者它们的一些组合上。使用$timeout可以修复所有问题,但我不知道为什么,使用计时器会产生不好的代码味道。一定有更好的方法 我可以手动调用验证函数,使视图与模型内联:
angular.element(document.querySelectorAll('.cb')).scope().checkBoxes()
…让我觉得我是在踏入$digest循环
..
以下仅在使用$timeout时有效:
angular.module('app', []).
controller('testCtrl', function ($scope, $timeout) {
$scope.guests = [
{name:'stephen', lname:'wille'},
{name:'mary', lname:'torccaso'}
];
$scope.form = {};
$scope.form.cb = {one:false, two:false, three:false, four:false}
$scope.showRequired = true;
$scope.checkBoxes = function ()
{
console.log('checkbox');
$scope.showRequired = !($scope.form.cb.one || $scope.form.cb.two ||
$scope.form.cb.three || $scope.form.cb.four);
$scope.$apply();
};
$scope.login = function () {
console.log('login');
};
angular.element(document.querySelectorAll('.cb'))
.on('click', function () {
console.log('click');
$scope.checkBoxes();
/*
* using the $timeout solves the problem, but why?
*
$timeout(function () {
$scope.checkBoxes();
}, 0, false);
*/
});
});
$timeout会触发另一个$digest,但$scoope.$apply()也会触发另一个$digest。那么是什么原因呢
您应该只使用ng click,而不是手动绑定DOM元素上的事件。此外,在控制器中访问DOM也不是一个好的做法。如果您让angular处理这些事件,您就不会遇到这些问题,您还可以安全地删除手动$digest调用($scope.$apply())。也可以使用
ng change
事件而不是ng click
来正确获取模型值,因为复选框的模型值在更改事件时得到更新
所以基本上你的脚本应该是:-
$scope.handleChange = function(){
$scope.checkBoxes();
};
$scope.handleChange = function(){
$scope.showRequired = $scope.form.cb.every(function(itm) {
return !itm.value;
});
};
和html:-
<input class="cb" type="checkbox" value="1" ng-model="form.cb.one"
ng-required="showRequired" ng-change="handleClick()">one</input>
<input class="cb" type="checkbox" value="2" ng-model="form.cb.two"
ng-required="showRequired" ng-change="handleClick()">two</input>
<input class="cb" type="checkbox" value="3" ng-model="form.cb.three"
ng-required="showRequired" ng-change="handleClick()">three</input>
<input class="cb" type="checkbox" value="4" ng-model="form.cb.four"
ng-required="showRequired" ng-change="handleClick()">four</input>
您可以只删除一个:-
<label ng-repeat="chk in form.cb">
<input class="cb" type="checkbox" value="{{$index}}"
ng-model="chk.value" ng-required="showRequired"
ng-change="handleChange()"/> {{chk.text}}</label>
现在这已经足够灵活了,它完全是模型驱动的,并且可以灵活地添加更多的复选框,而无需修改html或逻辑
$scope.handleChange = function(){
$scope.showRequired = $scope.form.cb.every(function(itm) {
return !itm.value;
});
};