Подтвердить что ты не робот

AngularJS: одиночный выбор между несколькими флажками

Я пытаюсь принудительно установить один флажок в ячейках, аналогично html "select"

У меня есть простая таблица html:

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

Тогда у меня есть некоторые простые функции контроллера для указанных выше директив:

$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;
    }
};

К сожалению, это не сработает, и я думаю, что я только что узнал, почему.... ng-click имеет приоритет 0, vs 100 для ng-checked.

Есть ли элегантное решение этой проблемы?

4b9b3361

Ответ 1

Привяжите ng-model к subscription.checked и ng-click снимите все подписки, кроме одного щелчка. Поскольку это флажки, один щелчок будет переключаться.

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

Вы можете использовать простой цикл for, но angular forEach позволяет нам использовать каждый элемент как subscription и улучшать читаемость:

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

Вот рабочая демонстрация: http://plnkr.co/edit/XD7r6PoTWpI4cBjdIZtv?p=preview

Ответ 2

<!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>

Ответ 3

Сверху моей головы я предлагаю вам один из трех вариантов.

  • Напишите директиву, которая будет устанавливать флажки для вас и управлять состоянием внутри них. Это не идеально, потому что вы настраиваете правило о своей модели (только одна подписка должна быть проверена) в проблему манипуляции с DOM.
  • Структурируйте свою модель таким образом, чтобы только одна подписка была отмечена как активная. Это сложно, потому что изменение модели при изменении приведет к запуску другого цикла дайджеста, а не того, что вы хотите.
  • Используйте переключатели вместо флажков. Это даст вам необходимую вам модальность. -Р

Я бы выбрал вариант 3 - я всегда поклонник использования собственных элементов ввода.

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

Ответ 4

Я использовал приведенный ниже код для достижения аналогичной функциональности. Trick - использовать ng-click, который может дать это довольно красиво. 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>