我正在使用 AngularJS v1.2.0-rc.3。
我有一个模型 y,与模型 x 有一对多的关系。
最初,我有一个模型 y 的表格,其中 xs 有多个选择,如下所示:
控制器:
function test($scope) {
$scope.xs = [
{id:1, value:'value 1'},
{id:2, value:'value 2'},
{id:3, value:'value 3'}
];
$scope.y = {xs:[2]};
}
看法:
<div ng-controller="test">
<select multiple ng-model="y.xs" ng-options="x.id as x.value for x in xs">
</select>
</div>
结果是所选项目的数组。
http://plnkr.co/edit/s3tvvHeyE17TVH5KNkPZ
一切都很好,但我需要将其更改为复选框列表,发现我不能再使用数组了。
我尝试使用中继器的索引,如下所示:
<div ng-repeat="x in xs">
<input type="checkbox" ng-model="y.xs[$index]" ng-true-value="{{x.id}}"/>
{{x.value}}
</div>
但是例如,要预先选择第二个项目,我需要使用它:
$scope.y = {xs: [null, '2']};
这是没用的。
http://plnkr.co/edit/9UfbKF2gFLnhTOKu3Yep
经过一番搜索,似乎推荐的方法是使用对象哈希,就像这样
<div ng-repeat="x in xs">
<input type="checkbox" ng-model="y.xs[x.id]"/>
{{x.value}}
</div>
http://plnkr.co/edit/Xek8alEJbwq3g0NAPMcF
但是如果取消选择项目,您最终会得到如下所示的内容:
y={
"xs": {
"1": false,
"2": false,
"3": false
}
}
所以我最终添加了一个监视表达式来过滤掉错误值,如下所示:
$scope.$watch('y.xs', function(n) {
for (var k in n)
if (n.hasOwnProperty(k) && !n[k])
delete n[k];
}, true);
http://plnkr.co/edit/S1C1g5fYKzUZb7b0pRtp
它有效,但感觉不令人满意。
由于这是一个常见的用例,我很想知道其他人是如何解决它的。
更新
按照使用自定义指令的建议,我想出了这个解决方案,它将选择保持为一个列表。
指示:
angular.module('checkbox', [])
.directive('checkboxList', function () {
return {
restrict: 'A',
replace: true,
scope: {
selection: '=',
items: '=',
value: '@',
label: '@'
},
template: '<div ng-repeat="item in list">' +
'<label>' +
'<input type="checkbox" value="{{item.value}}" ng-checked="item.checked" ng-click="toggle($index)"/>' +
'{{item.label}}' +
'</label>' +
'</div>',
controller: ['$scope', function ($scope) {
$scope.toggle = function (index) {
var item = $scope.list[index],
i = $scope.selection.indexOf(item.value);
item.checked = !item.checked;
if (!item.checked && i > -1) {
$scope.selection.splice(i, 1);
} else if (item.checked && i < 0) {
$scope.selection.push(item.value);
}
};
$scope.$watch('items', function (value) {
$scope.list = [];
if (angular.isArray(value)) {
angular.forEach(value, function (item) {
$scope.list.push({
value: item[$scope.value],
label: item[$scope.label],
checked: $scope.selection.indexOf(item[$scope.value]) > -1
});
});
}
}, true);
}]
};
});
看法:
<div checkbox-list
selection="a.bs"
items="bs"
value="id"
label="name">
</div>