您可以使用lodash库轻松地操作数组和集合。
EDIT-1:我添加了一个替代方案并相应地修改了 plunker。
EDIT-2:我使用自定义过滤器添加了另一种选择
演示: http ://plnkr.co/edit/Sf3el0FyUptWq28XqZnI?p=preview
假设您有一定数量的行(列表),每行都有一个下拉列表(选择)。下拉列表必须包含所有尚未选择的值(剩余)。
html
<ul>
<li ng-repeat="item in list">
{{item.id}}-{{item.value}}
<select ng-model="item.value" ng-options="letter for letter in remaining"></select>
</li>
</ul>
每当列表中的一项更改下拉值时,都会更新其余值。
js
$scope.$watch('list', function(newval) {
$scope.remaining = _.difference($scope.letters, _.map(newval, 'value'));
}, true);
可能的值列表:
$scope.letters = [
'A','B','C','D','E','F','G','H','I','J'
]
物品清单:
$scope.list = [
{id:1,value:''},
{id:2,value:''},
{id:3,value:''},
{id:4,value:''},
{id:5,value:''},
{id:6,value:''},
{id:7,value:''},
{id:8,value:''}
];
罗达什
我们使用 lodash 轻松地将列表中所有项目_.map
的value
属性设置为数组。我们想要_.difference
选择的值和可能的值之间的值。
替代跟踪以前的值
如果您的可能值列表表示为字符串 ( $scope.letters='ABCDEFGHIJ';
),那么您也可以将剩余值作为字符串 ( ) 来跟踪$scope.remaining='BDEGHJ';
。然后,$watch
您可以使用ng-change
下拉菜单上的指令并使用简单的string.replace
. 您需要跟踪先前选择的值,以便在切换时将它们放回列表中。
html
<ul>
<li ng-repeat="item in list2">
{{item.id}}-{{item.value}}
<select ng-model="item.value" ng-change="select(item)" ng-options="letter for letter in remaining2"></select>
</li>
</ul>
js
var last = [];
$scope.select = function(item) {
$scope.remaining2 = $scope.remaining2.replace(item.value,last[item.id]||'');
last[item.id] = item.value;
}
在这里,我使用item.id
来跟踪每个项目的先前值,但您可以考虑另一种方法。
使用过滤器的替代方案
这尚未经过测试,但它应该可以工作。
还有很多其他方法可以实现这一点,例如,在所有可能值的列表上使用自定义 $filter(过滤器需要访问当前选择的值)。它可能是我的一个解决方案的简单包装。
html
<select ng-model="item.value" ng-options="letter for letter in letters | notselected:list:'value'"></select>
这将作为输入$scope.letters
并删除$scope.list
. 我们必须告诉过滤器哪个属性对应于集合中的选定值。
js
app.filter('notselected', function() {
return function(input, list, prop) {
return _.difference(input, _.map(list, prop));
}
});
在我看来,这可能是最优雅的解决方案。Lodash 是一个了不起的库,与 Angular 一起工作就像一个魅力!