У меня есть несколько флажков:
<input type='checkbox' value="apple" checked>
<input type='checkbox' value="orange">
<input type='checkbox' value="pear" checked>
<input type='checkbox' value="naartjie">
Что я хотел бы привязать к списку в моем контроллере, так что всякий раз, когда изменяется флажок, контроллер ведет список всех проверенных значений, например ['apple', 'pear']
.
ng-model, по-видимому, может привязывать значение одного единственного флажка к переменной в контроллере.
Есть ли другой способ сделать это, чтобы я мог привязать четыре флажка к списку в контроллере?
Есть два способа подойти к этой проблеме. Или используйте простой массив или массив объектов. У каждого решения есть плюсы и минусы. Ниже вы найдете по одному для каждого случая.
HTML может выглядеть так:
<label ng-repeat="fruitName in fruits">
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruitName}}"
ng-checked="selection.indexOf(fruitName) > -1"
ng-click="toggleSelection(fruitName)"
> {{fruitName}}
</label>
И соответствующий код контроллера будет:
app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
// Fruits
$scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
// Selected fruits
$scope.selection = ['apple', 'pear'];
// Toggle selection for a given fruit by name
$scope.toggleSelection = function toggleSelection(fruitName) {
var idx = $scope.selection.indexOf(fruitName);
// Is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// Is newly selected
else {
$scope.selection.push(fruitName);
}
};
}]);
Преимущества: простая структура данных и переключение по имени просты в обращении
Минусы: добавление/удаление является громоздким, поскольку нужно управлять двумя списками (ввод и выбор)
HTML может выглядеть так:
<label ng-repeat="fruit in fruits">
<!--
- Use `value="{{fruit.name}}"` to give the input a real value, in case the form gets submitted
traditionally
- Use `ng-checked="fruit.selected"` to have the checkbox checked based on some angular expression
(no two-way-data-binding)
- Use `ng-model="fruit.selected"` to utilize two-way-data-binding. Note that `.selected`
is arbitrary. The property name could be anything and will be created on the object if not present.
-->
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruit.name}}"
ng-model="fruit.selected"
> {{fruit.name}}
</label>
И соответствующий код контроллера будет:
app.controller('ObjectArrayCtrl', ['$scope', 'filterFilter', function ObjectArrayCtrl($scope, filterFilter) {
// Fruits
$scope.fruits = [
{ name: 'apple', selected: true },
{ name: 'orange', selected: false },
{ name: 'pear', selected: true },
{ name: 'naartjie', selected: false }
];
// Selected fruits
$scope.selection = [];
// Helper method to get selected fruits
$scope.selectedFruits = function selectedFruits() {
return filterFilter($scope.fruits, { selected: true });
};
// Watch fruits for changes
$scope.$watch('fruits|filter:{selected:true}', function (nv) {
$scope.selection = nv.map(function (fruit) {
return fruit.name;
});
}, true);
}]);
Преимущества: добавление/удаление очень просто
Концы: несколько более сложная структура данных и переключение по имени громоздко или требует вспомогательного метода
value="{{fruit.name}}"
и ng-checked="fruit.checked"
излишни, так как используется ng-модель.
Простое решение:
<div ng-controller="MainCtrl">
<label ng-repeat="(color,enabled) in colors">
<input type="checkbox" ng-model="colors[color]" /> {{color}}
</label>
<p>colors: {{colors}}</p>
</div>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope){
$scope.colors = {Blue: true, Orange: true};
});
</script>
Вот небольшая многократная директива, которая, похоже, делает то, что вы хотите сделать. Я просто назвал его checkList
. Он обновляет массив при изменении флажков и обновляет флажки при изменении массива.
app.directive('checkList', function() {
return {
scope: {
list: '=checkList',
value: '@'
},
link: function(scope, elem, attrs) {
var handler = function(setup) {
var checked = elem.prop('checked');
var index = scope.list.indexOf(scope.value);
if (checked && index == -1) {
if (setup) elem.prop('checked', false);
else scope.list.push(scope.value);
} else if (!checked && index != -1) {
if (setup) elem.prop('checked', true);
else scope.list.splice(index, 1);
}
};
var setupHandler = handler.bind(null, true);
var changeHandler = handler.bind(null, false);
elem.bind('change', function() {
scope.$apply(changeHandler);
});
scope.$watch('list', setupHandler, true);
}
};
});
Здесь находится контроллер и представление, показывающее, как вы можете его использовать.
<div ng-app="myApp" ng-controller='MainController'>
<span ng-repeat="fruit in fruits">
<input type='checkbox' value="{{fruit}}" check-list='checked_fruits'> {{fruit}}<br />
</span>
<div>The following fruits are checked: {{checked_fruits | json}}</div>
<div>Add fruit to the array manually:
<button ng-repeat="fruit in fruits" ng-click='addFruit(fruit)'>{{fruit}}</button>
</div>
</div>
app.controller('MainController', function($scope) {
$scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
$scope.checked_fruits = ['apple', 'pear'];
$scope.addFruit = function(fruit) {
if ($scope.checked_fruits.indexOf(fruit) != -1) return;
$scope.checked_fruits.push(fruit);
};
});
(Кнопки показывают, что изменение массива также обновит флажки.)
Наконец, вот пример директивы в действии на Plunker: http://plnkr.co/edit/3YNLsyoG4PIBW6Kj7dRK?p=preview
<input type='checkbox' ng-repeat="fruit in fruits"
ng-checked="checkedFruits.indexOf(fruit) != -1" ng-click="toggleCheck(fruit)">
.
function SomeCtrl ($scope) {
$scope.fruits = ["apple, orange, pear, naartjie"];
$scope.checkedFruits = [];
$scope.toggleCheck = function (fruit) {
if ($scope.checkedFruits.indexOf(fruit) === -1) {
$scope.checkedFruits.push(fruit);
} else {
$scope.checkedFruits.splice($scope.checkedFruits.indexOf(fruit), 1);
}
};
}
На основе ответов в этом потоке я создал директиву checklist-model, которая охватывает все случаи:
Для темы-стартера это будет:
<label ng-repeat="fruit in ['apple', 'orange', 'pear', 'naartjie']">
<input type="checkbox" checklist-model="selectedFruits" checklist-value="fruit"> {{fruit}}
</label>
selectedFruits
.
checklist-model
директива по GitHub от Виталия Потапова абсолютно сработала для меня (с использованием сложных объектов).
Я потратил несколько часов, пытаясь заставить другие решения работать без везения. Отличная работа, жизнерадостные!
checklist-model
фактически ответил на этот вопрос выше: stackoverflow.com/a/19966119/1852787
Использование строки $index
может помочь использовать хэш-карту выбранных значений:
<ul>
<li ng-repeat="someItem in someArray">
<input type="checkbox" ng-model="someObject[$index.toString()]" />
</li>
</ul>
Таким образом, объект ng-model обновляется ключом, представляющим индекс.
$scope.someObject = {};
Через некоторое время $scope.someObject
должно выглядеть примерно так:
$scope.someObject = {
0: true,
4: false,
1: true
};
Этот метод не будет работать для всех ситуаций, но его легко реализовать.
Поскольку вы приняли ответ, в котором список не был использован, я буду считать, что ответ на мой вопрос комментариев "Нет, это не обязательно должен быть список". У меня также сложилось впечатление, что, возможно, вы растеряли сервер HTML, так как "check" присутствует в вашем примере HTML (это не понадобилось, если ng-model использовалась для моделирования ваших флажков).
В любом случае, вот что я имел в виду, когда задавал вопрос, также предполагая, что вы создаете серверную часть HTML:
<div ng-controller="MyCtrl"
ng-init="checkboxes = {apple: true, orange: false, pear: true, naartjie: false}">
<input type="checkbox" ng-model="checkboxes.apple">apple
<input type="checkbox" ng-model="checkboxes.orange">orange
<input type="checkbox" ng-model="checkboxes.pear">pear
<input type="checkbox" ng-model="checkboxes.naartjie">naartjie
<br>{{checkboxes}}
</div>
ng-init позволяет сформированному на стороне сервера HTML сначала устанавливать определенные флажки.
Проверьте эту директиву, которая эффективно управляет списками флажков. Надеюсь, это сработает для вас. CheckList Model
Другая простая директива может быть такой:
var appModule = angular.module("appModule", []);
appModule.directive("checkList", [function () {
return {
restrict: "A",
scope: {
selectedItemsArray: "=",
value: "@"
},
link: function (scope, elem) {
scope.$watchCollection("selectedItemsArray", function (newValue) {
if (_.contains(newValue, scope.value)) {
elem.prop("checked", true);
} else {
elem.prop("checked", false);
}
});
if (_.contains(scope.selectedItemsArray, scope.value)) {
elem.prop("checked", true);
}
elem.on("change", function () {
if (elem.prop("checked")) {
if (!_.contains(scope.selectedItemsArray, scope.value)) {
scope.$apply(
function () {
scope.selectedItemsArray.push(scope.value);
}
);
}
} else {
if (_.contains(scope.selectedItemsArray, scope.value)) {
var index = scope.selectedItemsArray.indexOf(scope.value);
scope.$apply(
function () {
scope.selectedItemsArray.splice(index, 1);
});
}
}
console.log(scope.selectedItemsArray);
});
}
};
}]);
Контроллер:
appModule.controller("sampleController", ["$scope",
function ($scope) {
//#region "Scope Members"
$scope.sourceArray = [{ id: 1, text: "val1" }, { id: 2, text: "val2" }];
$scope.selectedItems = ["1"];
//#endregion
$scope.selectAll = function () {
$scope.selectedItems = ["1", "2"];
};
$scope.unCheckAll = function () {
$scope.selectedItems = [];
};
}]);
И HTML:
<ul class="list-unstyled filter-list">
<li data-ng-repeat="item in sourceArray">
<div class="checkbox">
<label>
<input type="checkbox" check-list selected-items-array="selectedItems" value="{{item.id}}">
{{item.text}}
</label>
</div>
</li>
Я также включаю Plunker: http://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview
Я адаптировал Yoshi принятый ответ для обработки сложных объектов (вместо строк).
HTML
<div ng-controller="TestController">
<p ng-repeat="permission in allPermissions">
<input type="checkbox" ng-checked="selectedPermissions.containsObjectWithProperty('id', permission.id)" ng-click="toggleSelection(permission)" />
{{permission.name}}
</p>
<hr />
<p>allPermissions: | <span ng-repeat="permission in allPermissions">{{permission.name}} | </span></p>
<p>selectedPermissions: | <span ng-repeat="permission in selectedPermissions">{{permission.name}} | </span></p>
</div>
JavaScript
Array.prototype.indexOfObjectWithProperty = function(propertyName, propertyValue)
{
for (var i = 0, len = this.length; i < len; i++) {
if (this[i][propertyName] === propertyValue) return i;
}
return -1;
};
Array.prototype.containsObjectWithProperty = function(propertyName, propertyValue)
{
return this.indexOfObjectWithProperty(propertyName, propertyValue) != -1;
};
function TestController($scope)
{
$scope.allPermissions = [
{ "id" : 1, "name" : "ROLE_USER" },
{ "id" : 2, "name" : "ROLE_ADMIN" },
{ "id" : 3, "name" : "ROLE_READ" },
{ "id" : 4, "name" : "ROLE_WRITE" } ];
$scope.selectedPermissions = [
{ "id" : 1, "name" : "ROLE_USER" },
{ "id" : 3, "name" : "ROLE_READ" } ];
$scope.toggleSelection = function toggleSelection(permission) {
var index = $scope.selectedPermissions.indexOfObjectWithProperty('id', permission.id);
if (index > -1) {
$scope.selectedPermissions.splice(index, 1);
} else {
$scope.selectedPermissions.push(permission);
}
};
}
Рабочий пример: http://jsfiddle.net/tCU8v/
<input type="checkbox">
без переноса или соответствия <label>
! Теперь ваши пользователи должны нажимать на фактический флажок вместо текста рядом с флажком, что намного сложнее и плохо подходит для использования.
Я думаю, что самым простым способом было бы использовать "select" с "multiple":
<select ng-model="selectedfruit" multiple ng-options="v for v in fruit"></select>
В противном случае, я думаю, вам придется обработать список для создания списка
(через $watch()
привязка привязки модели к флажкам).
Существует способ работать с массивом напрямую и использовать ng-модель в то же время через ng-model-options="{ getterSetter: true }"
.
Фокус в том, чтобы использовать функцию getter/setter в вашей ng-модели. Таким образом, вы можете использовать массив как свою реальную модель и "подделку" логических элементов в модели ввода:
<label ng-repeat="fruitName in ['apple', 'orange', 'pear', 'naartjie']">
<input
type="checkbox"
ng-model="fruitsGetterSetterGenerator(fruitName)"
ng-model-options="{ getterSetter: true }"
> {{fruitName}}
</label>
$scope.fruits = ['apple', 'pear']; // pre checked
$scope.fruitsGetterSetterGenerator = function(fruitName){
return function myGetterSetter(nowHasFruit){
if (nowHasFruit !== undefined){
// Setter
fruitIndex = $scope.fruits.indexOf(fruit);
didHaveFruit = (fruitIndex !== -1);
mustAdd = (!didHaveFruit && nowHasFruit);
mustDel = (didHaveFruit && !nowHasFruit);
if (mustAdd){
$scope.fruits.push(fruit);
}
if (mustDel){
$scope.fruits.splice(fruitIndex, 1);
}
}
else {
// Getter
return $scope.user.fruits.indexOf(fruit) !== -1;
}
}
}
CAVEAT Вы не должны использовать этот метод, если ваши массивы большие, поскольку myGetterSetter
будет вызываться много раз.
Подробнее об этом см. https://docs.angularjs.org/api/ng/directive/ngModelOptions.
Следующее решение кажется хорошим вариантом,
<label ng-repeat="fruit in fruits">
<input
type="checkbox"
ng-model="fruit.checked"
ng-value="true"
> {{fruit.fruitName}}
</label>
И в модели контроллера значение fruits
будет таким:
$scope.fruits = [
{
"name": "apple",
"checked": true
},
{
"name": "orange"
},
{
"name": "grapes",
"checked": true
}
];
Вдохновленный с поста Йоши выше.
Вот plnkr.
(function () {
angular
.module("APP", [])
.controller("demoCtrl", ["$scope", function ($scope) {
var dc = this
dc.list = [
"Selection1",
"Selection2",
"Selection3"
]
dc.multipleSelections = []
dc.individualSelections = []
// Using splice and push methods to make use of
// the same "selections" object passed by reference to the
// addOrRemove function as using "selections = []"
// creates a new object within the scope of the
// function which doesn't help in two way binding.
dc.addOrRemove = function (selectedItems, item, isMultiple) {
var itemIndex = selectedItems.indexOf(item)
var isPresent = (itemIndex > -1)
if (isMultiple) {
if (isPresent) {
selectedItems.splice(itemIndex, 1)
} else {
selectedItems.push(item)
}
} else {
if (isPresent) {
selectedItems.splice(0, 1)
} else {
selectedItems.splice(0, 1, item)
}
}
}
}])
})()
label {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-app="APP" ng-controller="demoCtrl as dc">
<h1>checkbox-select demo</h1>
<h4>Multiple Selections</h4>
<label ng-repeat="thing in dc.list">
<input
type="checkbox"
ng-checked="dc.multipleSelections.indexOf(thing) > -1"
ng-click="dc.addOrRemove(dc.multipleSelections, thing, true)"
> {{thing}}
</label>
<p>
dc.multipleSelections :- {{dc.multipleSelections}}
</p>
<hr>
<h4>Individual Selections</h4>
<label ng-repeat="thing in dc.list">
<input
type="checkbox"
ng-checked="dc.individualSelections.indexOf(thing) > -1"
ng-click="dc.addOrRemove(dc.individualSelections, thing, false)"
> {{thing}}
</label>
<p>
dc.invidualSelections :- {{dc.individualSelections}}
</p>
<script data-require="[email protected]" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script data-require="[email protected]" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Если у вас есть несколько флажков в одной форме
Код контроллера
vm.doYouHaveCheckBox = ['aaa', 'ccc', 'bbb'];
vm.desiredRoutesCheckBox = ['ddd', 'ccc', 'Default'];
vm.doYouHaveCBSelection = [];
vm.desiredRoutesCBSelection = [];
Просмотреть код
<div ng-repeat="doYouHaveOption in vm.doYouHaveCheckBox">
<div class="action-checkbox">
<input id="{{doYouHaveOption}}" type="checkbox" value="{{doYouHaveOption}}" ng-checked="vm.doYouHaveCBSelection.indexOf(doYouHaveOption) > -1" ng-click="vm.toggleSelection(doYouHaveOption,vm.doYouHaveCBSelection)" />
<label for="{{doYouHaveOption}}"></label>
{{doYouHaveOption}}
</div>
</div>
<div ng-repeat="desiredRoutesOption in vm.desiredRoutesCheckBox">
<div class="action-checkbox">
<input id="{{desiredRoutesOption}}" type="checkbox" value="{{desiredRoutesOption}}" ng-checked="vm.desiredRoutesCBSelection.indexOf(desiredRoutesOption) > -1" ng-click="vm.toggleSelection(desiredRoutesOption,vm.desiredRoutesCBSelection)" />
<label for="{{desiredRoutesOption}}"></label>
{{desiredRoutesOption}}
</div>
</div>
В HTML (предположим, что флажки находятся в первом столбце каждой строки в таблице).
<tr ng-repeat="item in fruits">
<td><input type="checkbox" ng-model="item.checked" ng-click="getChecked(item)"></td>
<td ng-bind="fruit.name"></td>
<td ng-bind="fruit.color"></td>
...
</tr>
В файле controllers.js
:
// The data initialization part...
$scope.fruits = [
{
name: ....,
color:....
},
{
name: ....,
color:....
}
...
];
// The checked or not data is stored in the object array elements themselves
$scope.fruits.forEach(function(item){
item.checked = false;
});
// The array to store checked fruit items
$scope.checkedItems = [];
// Every click on any checkbox will trigger the filter to find checked items
$scope.getChecked = function(item){
$scope.checkedItems = $filter("filter")($scope.fruits,{checked:true});
};
Мне нравится ответ Йоши. Я улучшил его, поэтому вы можете использовать одну и ту же функцию для нескольких списков.
<label ng-repeat="fruitName in fruits">
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruitName}}"
ng-checked="selection.indexOf(fruitName) > -1"
ng-click="toggleSelection(fruitName, selection)"> {{fruitName}}
</label>
<label ng-repeat="veggieName in veggies">
<input
type="checkbox"
name="selectedVeggies[]"
value="{{veggieName}}"
ng-checked="veggieSelection.indexOf(veggieName) > -1"
ng-click="toggleSelection(veggieName, veggieSelection)"> {{veggieName}}
</label>
app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
// fruits
$scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
$scope.veggies = ['lettuce', 'cabbage', 'tomato']
// selected fruits
$scope.selection = ['apple', 'pear'];
$scope.veggieSelection = ['lettuce']
// toggle selection for a given fruit by name
$scope.toggleSelection = function toggleSelection(selectionName, listSelection) {
var idx = listSelection.indexOf(selectionName);
// is currently selected
if (idx > -1) {
listSelection.splice(idx, 1);
}
// is newly selected
else {
listSelection.push(selectionName);
}
};
}]);
Вот еще одно решение. Поверхность моего решения:
Вот директива:
function ensureArray(o) {
var lAngular = angular;
if (lAngular.isArray(o) || o === null || lAngular.isUndefined(o)) {
return o;
}
return [o];
}
function checkboxArraySetDirective() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var name = attrs.checkboxArraySet;
ngModel.$formatters.push(function(value) {
return (ensureArray(value) || []).indexOf(name) >= 0;
});
ngModel.$parsers.push(function(value) {
var modelValue = ensureArray(ngModel.$modelValue) || [],
oldPos = modelValue.indexOf(name),
wasSet = oldPos >= 0;
if (value) {
if (!wasSet) {
modelValue = angular.copy(modelValue);
modelValue.push(name);
}
} else if (wasSet) {
modelValue = angular.copy(modelValue);
modelValue.splice(oldPos, 1);
}
return modelValue;
});
}
}
}
В конце концов просто используйте его так:
<input ng-repeat="fruit in ['apple', 'banana', '...']" type="checkbox" ng-model="fruits" checkbox-array-set="{{fruit}}" />
И это все, что есть. Единственным дополнением является атрибут checkbox-array-set
.
Вы можете комбинировать AngularJS и jQuery. Например, вам нужно определить массив, $scope.selected = [];
, в контроллере.
<label ng-repeat="item in items">
<input type="checkbox" ng-model="selected[$index]" ng-true-value="'{{item}}'">{{item}}
</label>
Вы можете получить массив, владеющий выбранными элементами. Используя метод alert(JSON.stringify($scope.selected))
, вы можете проверить выбранные элементы.
Вам не нужно писать весь этот код. AngularJS будет держать модель и флажки в синхронизации просто с помощью ngTrueValue и ngFalseValue
Codepen здесь: http://codepen.io/paulbhartzog/pen/kBhzn
Фрагмент кода:
<p ng-repeat="item in list1" class="item" id="{{item.id}}">
<strong>{{item.id}}</strong> <input name='obj1_data' type="checkbox" ng-model="list1[$index].data" ng-true-value="1" ng-false-value="0"> Click this to change data value below
</p>
<pre>{{list1 | json}}</pre>
Основываясь на моем другом сообщении здесь, я сделал многоразовую директиву.
Посмотрите репозиторий GitHub
(function () {
angular
.module("checkbox-select", [])
.directive("checkboxModel", ["$compile", function ($compile) {
return {
restrict: "A",
link: function (scope, ele, attrs) {
// Defining updateSelection function on the parent scope
if (!scope.$parent.updateSelections) {
// Using splice and push methods to make use of
// the same "selections" object passed by reference to the
// addOrRemove function as using "selections = []"
// creates a new object within the scope of the
// function which doesn't help in two way binding.
scope.$parent.updateSelections = function (selectedItems, item, isMultiple) {
var itemIndex = selectedItems.indexOf(item)
var isPresent = (itemIndex > -1)
if (isMultiple) {
if (isPresent) {
selectedItems.splice(itemIndex, 1)
} else {
selectedItems.push(item)
}
} else {
if (isPresent) {
selectedItems.splice(0, 1)
} else {
selectedItems.splice(0, 1, item)
}
}
}
}
// Adding or removing attributes
ele.attr("ng-checked", attrs.checkboxModel + ".indexOf(" + attrs.checkboxValue + ") > -1")
var multiple = attrs.multiple ? "true" : "false"
ele.attr("ng-click", "updateSelections(" + [attrs.checkboxModel, attrs.checkboxValue, multiple].join(",") + ")")
// Removing the checkbox-model attribute,
// it will avoid recompiling the element infinitly
ele.removeAttr("checkbox-model")
ele.removeAttr("checkbox-value")
ele.removeAttr("multiple")
$compile(ele)(scope)
}
}
}])
// Defining app and controller
angular
.module("APP", ["checkbox-select"])
.controller("demoCtrl", ["$scope", function ($scope) {
var dc = this
dc.list = [
"selection1",
"selection2",
"selection3"
]
// Define the selections containers here
dc.multipleSelections = []
dc.individualSelections = []
}])
})()
label {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-app="APP" ng-controller="demoCtrl as dc">
<h1>checkbox-select demo</h1>
<h4>Multiple Selections</h4>
<label ng-repeat="thing in dc.list">
<input type="checkbox" checkbox-model="dc.multipleSelections" checkbox-value="thing" multiple>
{{thing}}
</label>
<p>dc.multipleSelecitons:- {{dc.multipleSelections}}</p>
<h4>Individual Selections</h4>
<label ng-repeat="thing in dc.list">
<input type="checkbox" checkbox-model="dc.individualSelections" checkbox-value="thing">
{{thing}}
</label>
<p>dc.individualSelecitons:- {{dc.individualSelections}}</p>
<script data-require="[email protected]" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script data-require="[email protected]" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
<div ng-app='app' >
<div ng-controller='MainCtrl' >
<ul>
<li ng-repeat="tab in data">
<input type='checkbox' ng-click='change($index,confirm)' ng-model='confirm' />
{{tab.name}}
</li>
</ul>
{{val}}
</div>
</div>
var app = angular.module('app', []);
app.controller('MainCtrl',function($scope){
$scope.val=[];
$scope.confirm=false;
$scope.data=[
{
name:'vijay'
},
{
name:'krishna'
},{
name:'Nikhil'
}
];
$scope.temp;
$scope.change=function(index,confirm){
console.log(confirm);
if(!confirm){
($scope.val).push($scope.data[index]);
}
else{
$scope.temp=$scope.data[index];
var d=($scope.val).indexOf($scope.temp);
if(d!=undefined){
($scope.val).splice(d,1);
}
}
}
})
Используя этот пример в @Umur Kontacı, я думаю, что при использовании для захвата выбранных данных по всему другому объекту/массиву, например, на странице редактирования.
В качестве примера, все цвета json внизу:
{
"colors": [
{
"id": 1,
"title": "Preto - #000000"
},
{
"id": 2,
"title": "Azul - #005AB1"
},
{
"id": 3,
"title": "Azul Marinho - #001A66"
},
{
"id": 4,
"title": "Amarelo - #FFF100"
},
{
"id": 5,
"title": "Vermelho - #E92717"
},
{
"id": 6,
"title": "Verde - #008D2F"
},
{
"id": 7,
"title": "Cinza - #8A8A8A"
},
{
"id": 8,
"title": "Prata - #C8C9CF"
},
{
"id": 9,
"title": "Rosa - #EF586B"
},
{
"id": 10,
"title": "Nude - #E4CAA6"
},
{
"id": 11,
"title": "Laranja - #F68700"
},
{
"id": 12,
"title": "Branco - #FFFFFF"
},
{
"id": 13,
"title": "Marrom - #764715"
},
{
"id": 14,
"title": "Dourado - #D9A300"
},
{
"id": 15,
"title": "Bordo - #57001B"
},
{
"id": 16,
"title": "Roxo - #3A0858"
},
{
"id": 18,
"title": "Estampado "
},
{
"id": 17,
"title": "Bege - #E5CC9D"
}
]
}
И 2 типа объекта данных, array
с одним объектом и object
, содержащим два и более данных объекта:
В базе данных выбраны два элемента:
[{"id":12,"title":"Branco - #FFFFFF"},{"id":16,"title":"Roxo - #3A0858"}]
Один элемент, выбранный в базе данных:
{"id":12,"title":"Branco - #FFFFFF"}
И вот, мой код javascript:
/**
* Add this code after catch data of database.
*/
vm.checkedColors = [];
var _colorObj = vm.formData.color_ids;
var _color_ids = [];
if (angular.isObject(_colorObj)) {
// vm.checkedColors.push(_colorObj);
_color_ids.push(_colorObj);
} else if (angular.isArray(_colorObj)) {
angular.forEach(_colorObj, function (value, key) {
// vm.checkedColors.push(key + ':' + value);
_color_ids.push(key + ':' + value);
});
}
angular.forEach(vm.productColors, function (object) {
angular.forEach(_color_ids, function (color) {
if (color.id === object.id) {
vm.checkedColors.push(object);
}
});
});
/**
* Add this code in your js function initialized in this HTML page
*/
vm.toggleColor = function (color) {
console.log('toggleColor is: ', color);
if (vm.checkedColors.indexOf(color) === -1) {
vm.checkedColors.push(color);
} else {
vm.checkedColors.splice(vm.checkedColors.indexOf(color), 1);
}
vm.formData.color_ids = vm.checkedColors;
};
Мой HTML-код:
<div class="checkbox" ng-repeat="color in productColors">
<label>
<input type="checkbox"
ng-checked="checkedColors.indexOf(color) != -1"
ng-click="toggleColor(color)"/>
<% color.title %>
</label>
</div>
<p>checkedColors Output:</p>
<pre><% checkedColors %></pre>
function makeCheckedOptions(objectOptions, optionObj) {
var checkedOptions = [];
var savedOptions = [];
if (angular.isObject(optionObj)) {
savedOptions.push(optionObj);
} else if (angular.isArray(optionObj)) {
angular.forEach(optionObj, function (value, key) {
savedOptions.push(key + ':' + value);
});
}
angular.forEach(objectOptions, function (object) {
angular.forEach(savedOptions, function (color) {
if (color.id === object.id) {
checkedOptions.push(object);
}
});
});
return checkedOptions;
}
И вызовите новый метод, как показано ниже:
vm.checkedColors = makeCheckedOptions(productColors, vm.formData.color_ids);
Что это!
Простой HTML-способ:
<input type="checkbox"
ng-checked="fruits.indexOf('apple') > -1"
ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('apple')">
<input type="checkbox"
ng-checked="fruits.indexOf('orange') > -1"
ng-click="fruits.indexOf('orange') > -1 ? fruits.splice(fruits.indexOf('orange'), 1) : fruits.push('orange')">
<input type="checkbox"
ng-checked="fruits.indexOf('pear') > -1"
ng-click="fruits.indexOf('pear') > -1 ? fruits.splice(fruits.indexOf('pear'), 1) : fruits.push('pear')">
<input type="checkbox"
ng-checked="fruits.indexOf('naartjie') > -1"
ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('naartjie')">
Посмотрите это: checklist-model.
Он работает с массивами JavaScript и объектами и может использовать статические HTML-флажки без ng-repeat
<label><input type="checkbox" checklist-model="roles" value="admin"> Administrator</label>
<label><input type="checkbox" checklist-model="roles" value="customer"> Customer</label>
<label><input type="checkbox" checklist-model="roles" value="guest"> Guest</label>
<label><input type="checkbox" checklist-model="roles" value="user"> User</label>
И сторона JavaScript:
var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl4a', function($scope) {
$scope.roles = [];
});
Я поставил массив в контроллер.
$scope.statuses = [{ name: 'Shutdown - Reassessment Required' },
{ name: 'Under Construction' },
{ name: 'Administrative Cancellation' },
{ name: 'Initial' },
{ name: 'Shutdown - Temporary' },
{ name: 'Decommissioned' },
{ name: 'Active' },
{ name: 'SO Shutdown' }]
В разметке я поставил что-то вроде следующего
<div ng-repeat="status in $scope.statuses">
<input type="checkbox" name="unit_status" ng-model="$scope.checkboxes[status.name]"> {{status.name}}
<br>
</div>
{{$scope.checkboxes}}
Выход был следующим: в контроллере мне просто нужно было проверить, истинно это или ложно; true для checked, absent/false для unchecked.
{
"Administrative Cancellation":true,
"Under Construction":true,
"Shutdown - Reassessment Required":true,
"Decommissioned":true,
"Active":true
}
Надеюсь, что это поможет.
Вот ссылка jsFillde для того же самого, http://jsfiddle.net/techno2mahi/Lfw96ja6/.
Это использует директиву, доступную для загрузки http://vitalets.github.io/checklist-model/.
Это полезно иметь директиву, так как ваше приложение будет очень часто нуждаться в этой функции.
Код ниже:
<div class="container">
<div class="ng-scope" ng-app="app" ng-controller="Ctrl1">
<div class="col-xs-12 col-sm-6">
<h3>Multi Checkbox List Demo</h3>
<div class="well"> <!-- ngRepeat: role in roles -->
<label ng-repeat="role in roles">
<input type="checkbox" checklist-model="user.roles" checklist-value="role"> {{role}}
</label>
</div>
<br>
<button ng-click="checkAll()">check all</button>
<button ng-click="uncheckAll()">uncheck all</button>
<button ng-click="checkFirst()">check first</button>
<div>
<h3>Selected User Roles </h3>
<pre class="ng-binding">{{user.roles|json}}</pre>
</div>
<br>
<div><b/>Provided by techno2Mahi</b></div>
</div>
var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl1', function($scope) {
$scope.roles = [
'guest',
'user',
'customer',
'admin'
];
$scope.user = {
roles: ['user']
};
$scope.checkAll = function() {
$scope.user.roles = angular.copy($scope.roles);
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
});
<div>
чем закрывающих </div>
. Вы что-то упустили?
Я предлагаю использовать модуль AngularJS Dropdown Multiselect.
Я думаю, что следующий путь более ясен и полезен для вложенных ng-повторов. Проверьте это на Plunker.
<html ng-app="plunker">
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="tab in mytabs">
<h1>{{tab.name}}</h1>
<div ng-repeat="val in tab.values">
<input type="checkbox" ng-change="checkValues()" ng-model="val.checked"/>
</div>
</div>
<br>
<pre> {{selected}} </pre>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope,$filter) {
$scope.mytabs = [
{
name: "tab1",
values: [
{ value: "value1",checked:false },
{ value: "value2", checked: false },
{ value: "value3", checked: false },
{ value: "value4", checked: false }
]
},
{
name: "tab2",
values: [
{ value: "value1", checked: false },
{ value: "value2", checked: false },
{ value: "value3", checked: false },
{ value: "value4", checked: false }
]
}
]
$scope.selected = []
$scope.checkValues = function () {
angular.forEach($scope.mytabs, function (value, index) {
var selectedItems = $filter('filter')(value.values, { checked: true });
angular.forEach(selectedItems, function (value, index) {
$scope.selected.push(value);
});
});
console.log($scope.selected);
};
});
</script>
</body>
</html>
<input type='checkbox' ng-model="checkboxes.apple">
и т. Д. Модель будет: {"apple": true, "orange": false, "pear": true, " naartjie ": правда}