简体   繁体   English

AngularJS:在多个复选框之间单选

[英]AngularJS: single select between multiple checkbox

I am trying to force a single-selection on checkboxes, similar to a html "select" 我试图在复选框上强制单选,类似于html“select”

I have a html simple table: 我有一个简单的html表:

<tr ng-repeat="subscription in entities">
    <td>
        <input type="checkbox" ng-checked="isChecked(subscription)" ng-click="toggleSelection(subscription)"/>
    </td>
</tr> 

Then I have some simple controller functions for those directives above: 然后我有一些简单的控制器函数用于上面的指令:

$scope.isChecked = function(entity) {
    return $scope.checkedEntity === entity;
};

$scope.toggleSelection = function(entity) {
    entity.checked = !entity.checked;
    if (entity.checked) {
        $scope.checkedEntity = entity;
    } else {
        $scope.checkedEntity = null;
    }
};

Unfortunately it doesn't work, and I think I just discovered why.... the ng-click has 0 priority, vs 100 for ng-checked. 不幸的是它不起作用,我想我刚刚发现了...... ng-click有0优先级,而ng-checked有100。

Is there an elegant solution for this problem? 这个问题有优雅的解决方案吗?

Bind ng-model to subscription.checked , and have ng-click uncheck all subscriptions except the one clicked. ng-model绑定到subscription.checked ,并使用ng-click取消选中除单击之外的所有订阅。 Since these are checkboxes, the one clicked will toggle itself. 由于这些是复选框,因此单击的按钮将自动切换。

<tr ng-repeat="subscription in entities">
  <td>
    <input ng-model="subscription.checked" ng-click="updateSelection($index, entities)" type="checkbox" />
  </td>
</tr>

You can use a plain for loop, but angular's forEach allows us to alias each item as subscription and improve readability: 您可以使用plain for循环,但angular的forEach允许我们将每个项目别名为subscription并提高可读性:

$scope.updateSelection = function(position, entities) {
  angular.forEach(entities, function(subscription, index) {
    if (position != index) 
      subscription.checked = false;
  });
}

Here is a working demo: http://plnkr.co/edit/XD7r6PoTWpI4cBjdIZtv?p=preview 这是一个工作演示: http//plnkr.co/edit/XD7r6PoTWpI4cBjdIZtv?p = preview

 <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script> angular.module('app', []).controller('appc', ['$scope', function($scope) { $scope.selected = 'other'; } ]); </script> </head> <body ng-app="app" ng-controller="appc"> <label>SELECTED: {{selected}}</label> <div> <input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male <br> <input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female <br> <input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other </div> </body> </html> 

I have used the below code to achieve the similar functionality. 我使用下面的代码来实现类似的功能。 Trick is to use ng-click which can yield this pretty nicely. 诀窍是使用ng-click ,这可以很好地产生这种效果。 checkbox-1 & checkbox-2 are boolean in nature. checkbox-1和checkbox-2本质上是布尔值。

<form>
    <input type="checkbox" ng-click="checkbox-2 = false" ng-model="checkbox-1" >
    <input type="checkbox" ng-click="checkbox-1 = false" ng-model="checkbox-2" >
</form>

Off the top of my head, I'd suggest one of three options for you. 在我的头顶,我建议你选择三个选项之一。

  1. Write a directive that will set up the checkboxes for you and manage the state within them. 编写一个指令,为您设置复选框并管理其中的状态。 This isn't ideal, because you're turning a rule about your model (only one subscription should be checked) into DOM manipulation problem. 这并不理想,因为您正在将关于模型的规则(仅应检查一个订阅)转换为DOM操作问题。
  2. Structure your model such that only one subscription is ever marked active. 构建模型,使得只有一个订阅标记为活动。 This is tricky, because modifying the model on a change will kick off another digest cycle, not what you want. 这很棘手,因为在更改时修改模型将启动另一个摘要周期,而不是您想要的。
  3. Use radio buttons instead of checkboxes. 使用单选按钮而不是复选框。 That will get you the modality you want. 这将为您提供您想要的模态。 :-P :-P

I'd go with option 3--I'm always a fan of taking advantage of native input elements. 我选择3 - 我总是喜欢利用原生输入元素。

<tr ng-repeat="subscription in entities">
<td><input type="radio"
   ng-model="selection"
   name="subscriptionRadio"
   value="{{subscription}}"/>
</td> 
</tr>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM