下拉过滤多行

时间:2013-10-11 23:44:57

标签: javascript angularjs

我有多行,每行包含带标签的下拉列表。 标签=(“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”

1 个答案:

答案 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的魅力相似!