javascript - 如果使用 preventDefault,AngularJS 复选框 ng-checked 不呈现

标签 javascript angularjs checkbox

我正在动态构建一组复选框。单击任何复选框应取消选中第一个(索引方式)复选框。单击任何未选中的框应选中最后一个未选中的框。

我正在使用 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/

相关文章:

javascript - 简单的javascript变量问题

javascript - 类型 'Never' Typescript/React 上不存在属性

javascript - 在 VS 中,有没有办法忽略某些 typescript 文件上的错误但仍将它们编译进去?

javascript - Yeoman-Angular 生成的应用程序中缺少 Angular 脚本

javascript - Angular : Apply a directive only if element is a textarea

javascript - JsViews 复选框从内部循环绑定(bind)

javascript - 删除窗口调整大小的元素过渡,但保留过滤/显示/隐藏元素的过渡

javascript - AngularJS:如何使用 token 安全性和自定义方法处理 RESTful API?

javascript - 在 iCheck 复选框上检测 Shift 键 + 单击事件

css - 提交表单和刷新 Angular 范围变量时缺少复选框样式