我有多行,每行包含带标签的下拉列表。 标签=(“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,“L” ) 如果我们在第一行选择“A”作为标签,在第二行选择“B”,在第三行选择“C” 我们只应在下拉列表中显示所选标签和可用标签。 例如:在第一行下拉菜单中显示“A”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,“L” 这应该适合所有人。我正在使用javascript和angular js。 有人可以提供一个有效的方法来解决这个问题。 我有一个选择标签标志和showLabels标志的想法,但我们需要为每一行循环它,并且实时应用程序我可以有超过100行,并且不想为每一行循环100次。请帮忙。
| A ^ | |删除按钮|
| B ^ | |删除按钮|
在第一个下拉值中应为“A,C,D,E,F,G,H” 在第二个下拉值中应该是“B,C,D,E,F,G,H”
当我们添加一行时,我们得到一个新行,下拉列表应该包含“C,D,E,F,G,H”
答案 0 :(得分:1)
您可以使用lodash库轻松地操作数组和集合。
EDIT-1:我添加了一个替代方案,并相应地修改了plunker。
EDIT-2 :我使用自定义过滤器添加了另一种替代方法
DEMO: 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 强>
我们使用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的魅力相似!