AngularJS - переключатели ng-repeat с отменой выбора / отменой выбора
Я пытаюсь создать блок ng-repeat для переключателей. Мне нужно, чтобы кнопки были отменяемыми.
Вот пример блока ng-repeat:
<div ng-repeat="role in roles" class="checkbox checkbox-inline checkbox-primary">
<input id="{{ role.Value }}" ng-model="$parent.roleSelected" class="styled" type="radio"
name="{{ role.Group }}" value="{{ role.Value }}" />
<label for="{{ role.Value }}">{{ role.Name }}</label>
</div>
Редактировать: функция использования отменяемого переключателя при нажатии на ту же кнопку была предоставлена клиентом в качестве требования. Этот вопрос о том, как это можно сделать, а не о том, следует ли это делать.
2 ответа
Я провел поиск и обнаружил, что отмена выбора переключателей не так проста. Ниже приведен вопрос, который несколько его затронул, но, похоже, он не работает, когда выполняется в блоке ng-repeat: AngularJs. Можно ли отменить выбор "радио" ввода HTML нажатием кнопки?
Вот как я решил проблему. Сначала я настраиваю ng-repeat так:
<div ng-repeat="role in roles" class="checkbox checkbox-inline checkbox-primary">
<input id="{{ role.Value }}" ng-model="$parent.roleSelected" class="styled" type="radio"
name="{{ role.Group }}" value="{{ role.Value }}" ng-click="clickRole($event)" />
<label for="{{ role.Value }}">{{ role.Name }}</label>
</div>
В контроллере у меня есть два метода. Один для ng-click и тот, который следит за изменениями в ng-модели. У меня также есть массив ($scope.rolesSelected), который отслеживает выбранные роли. (У меня было несколько блоков ng-repeat на странице, некоторые были радио, некоторые были флажками).
Когда радио (или флажок) щелкается, оно выполняет функцию clickRole(), которая добавляет roleSelected к массиву roleSelected.
$scope.clickRole = function (event) {
if (event.target.type != 'radio') { // for checkboxes
addOrRemoveFromArray($scope.rolesSelected, event.target.value);
} else { // for radio - uncheck radio if selection was removed
var addedRole = addOrRemoveFromArray($scope.rolesSelected, event.target.value);
if (!addedRole) {
event.target.checked = false;
}
}
}
Функция addOrRemoveFromArray() просто добавляет данное значение, если его еще нет в массиве, в противном случае удаляет его. Это позволяет удалить выбранную роль, когда переключатель дважды щелкнул (один раз, чтобы добавить, второй, чтобы удалить его).
function addOrRemoveFromArray(array, value) {
if (typeof value == 'undefined') { return; }
var index = array.indexOf(value);
if (index > -1) {
array.splice(index, 1);
return false;
} else {
array.push(value);
return true;
}
}
Вплоть до этого он обрабатывает добавление роли и удаление роли, если отменить выбор. (также обрабатывает добавить / удалить для флажков). Но для радио, при выборе другой роли, она не удаляет предыдущую. Так что нужна еще одна функция watch() для этого на ng-модели.
$scope.$watch('roleSelected', function (newValue, oldValue) {
removeFromArray($scope.rolesSelected, oldValue);
});
Наконец, благодаря этому я смог справиться со сменой ролей на переключателях и отменой выбора.
Это заняло у меня много времени, чтобы разобраться, поэтому я публикую здесь сообщения на случай, если кто-нибудь еще столкнется с подобной ситуацией. Спасибо!
А как насчет использования флажка, а только с одним выбираемым элементом?
<div ng-repeat="role in roles" class="checkbox checkbox-inline checkbox-primary">
<input id="{{ role.Value }}" ng-click="setRole(role.Value)" ng-checked="role.Value == roleSelected" class="styled" type="checkbox"
name="{{ role.Group }}" value="{{ role.Value }}" />
<label for="{{ role.Value }}">{{ role.Name }}</label>
</div>
И код контроллера:
$scope.setRole = function(value)
{
if ($scope.roleSelected != value) {
$scope.roleSelected = value;
}
else {
$scope.roleSelected = null;
}
}
Демо - версия: