我正在动态构建一组复选框。单击任何复选框应取消选中第一个(索引方式)复选框。单击任何未选中的框应选中最后一个未选中的框。
我正在使用 ng-repeat 构建复选框,如下所示:
<input
type="checkbox"
ng-checked="values[$index]"
ng-repeat="n in values track by $index"
ng-click="click($event,$index)" />
我的 Controller 看起来像这样:
.controller("myCtrl", function ($scope) {
$scope.values = [true,true,true,true];
$scope.click = function (event,n) {
event.preventDefault();
if ($scope.values[n] === true) {
$scope.values[$scope.values.indexOf(true)] = false;
} else {
$scope.values[$scope.values.lastIndexOf(false)] = true;
}
}
这是所有内容的代码笔 http://codepen.io/anon/pen/rVLewJ
我遇到的问题是,使用 preventDefault 似乎会阻止 ng-checked 更新您单击的框的呈现(其他框会正确重新呈现)。这会导致显示与 $scope.values 不同步。
同样,删除 preventDefault 不会阻止您单击的框更改其渲染,但是(我相信是因为 ng-repeat 的保守重新渲染)ng-checked 不会触发,因此它也会退出同步。
我没有使用 ng-changed 是因为我特别试图防止复选框在您单击“错误”复选框时发生变化。无论如何,我已经尝试使用它而不是 ng-clicked 并且它没有解决任何问题。
我试过使用 ng-model 而不是 ng-checked,但这似乎完全阻止了 $scope.values 的改变。使用 $scope.$apply() 没有帮助。我读过的一些东西让我觉得我可能需要使用 $watch
但我正在通过这个项目自学 Angular,所以我不确定如何应用它。
更新
Nagasimha Iyengar 提供了一个可行的解决方案 here我已经这样简化了
<input
type="checkbox"
ng-model="values[$index]"
ng-repeat="n in values track by $index"
ng-change="click($index)" />
Controller :
.controller("myCtrl", function ($scope) {
$scope.values = [true,true,true,true];
$scope.click = function (n) {
if ($scope.values[n] === true) {//clicking on unchecked box
$scope.values[n] = false;
$scope.values[$scope.values.lastIndexOf(false)] = true;
} else {//clicking on checked box
$scope.values[n] = true;
$scope.values[$scope.values.indexOf(true)] = false;
}
}
代码笔:http://codepen.io/anon/pen/zGBKxr
此解决方案基于允许点击事件发生,然后在继续自定义逻辑之前撤消它。这当然是一个简单的解决方案,但感觉有些不合适。这是解决这个问题最正确的方法吗?
另一个小更新。我加入了 ngTouch 以尝试让应用程序在移动设备上感觉更快一些。至少在 iOS Safari 8 中,ngTouch 打破了这个解决方案。在桌面上仍然可以正常工作,但被覆盖的 ngClick 会阻止此解决方案的工作。如果您切换回最初建议的逻辑,它会修复 iOS,但当然不能在桌面上运行。我觉得这证实了我对解决方案不正确的怀疑。
最佳答案
就是这样 - 逻辑被颠倒了。我使用 $apply 超时。修改后的codepen:http://codepen.io/nagasimhai/pen/VLjjPe
angular
.module("myApp", [])
.controller("myCtrl", function ($scope) {
$scope.values = [true,true,true,true];
$scope.click = function (event,n) {
//event.preventDefault();
//console.log("b", n, $scope.values,$scope.values.indexOf(true), $scope.values.lastIndexOf(false));
if ($scope.values[n] === true) {//clicking on unchecked box
$scope.values[n] = false;
$scope.values[$scope.values.lastIndexOf(false)] = true;
//console.log("11");
} else {//clicking on checked box
$scope.values[n] = true;
$scope.values[$scope.values.indexOf(true)] = false;
//console.log('22');
}
//console.log("a",n, $scope.values);
setTimeout(function () {
$scope.$apply(function () {
});
}, 2000);
}
});
关于javascript - 如果使用 preventDefault,AngularJS 复选框 ng-checked 不呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30279017/