复选框组要求至少检查一个以启用提交按钮 取消选中所有复选框将禁用该按钮 所有复选框都使用相同的范围属性(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()。
什么给出了什么?
答案 0 :(得分:2)
您应该只使用ng-click而不是手动绑定DOM元素上的事件。此外,在控制器中访问DOM也不是一个好习惯。如果你把它放到angular来处理你不会遇到这些问题的事件,你也可以安全地删除手动的$ digest调用($ scope。$ apply())。还可以使用ng-change
事件而不是ng-click
来正确获取模型值,因为复选框的模型值会在更改事件中获得更新。
所以基本上你的脚本只是: -
$scope.handleChange = function(){
$scope.checkBoxes();
};
和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>
<强> Demo 强>
使用ng-repeat实际上可以更好地改善这一点。
如果您重新排列数组中的复选框: -
$scope.form.cb = [{text:'one', value:false}, {text:'two', value:false}, {text:'three', value:false}, {text:'four', value:false}];
你可以只取消一个: -
<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>
脚本将只是: -
$scope.handleChange = function(){
$scope.showRequired = $scope.form.cb.every(function(itm) {
return !itm.value;
});
};
现在这很灵活,它完全是模型驱动的,足够灵活,无需修改你的html或逻辑就可以添加更多复选框。
<强> Demo2 强>
<强> Array.prototype.every shim support for older browsers 强>