【问题标题】:dropdown filtering in multiple rows多行下拉过滤
【发布时间】:2013-10-11 23:44:57
【问题描述】:

我有多行,每行都包含一个带有标签的下拉菜单。 标签 =(“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、C、D、E、F、G、H” 在第二个下拉列表中的值应该是“B、C、D、E、F、G、H”

当我们添加一行时,我们会得到一个新行,下拉菜单应该包含“C,D,E,F,G,H”

【问题讨论】:

  • 我很困惑,据我了解:您有多个堆叠的、可点击的水平行(如菜单),当您单击一个时,您希望它不再显示?你能附上一张照片吗?如果你不熟练的话,就像在油漆上做点什么一样。或者展示一个在其他网站上运行的示例?
  • 您可以在下拉菜单发生时简单地生成列表
  • 您是否尝试过编写过滤器?然后你可以过滤你的 ng-repeat,如果它已经被选中,就把它扔掉。

标签: javascript angularjs


【解决方案1】:

您可以使用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

我们使用 lodash 轻松地将列表中的所有项目的_.mapvalue 属性转换为一个数组。我们希望_.difference 介于所选值和可能值之间。

替代跟踪以前的值

如果您的可能值列表表示为字符串 ($scope.letters='ABCDEFGHIJ';),那么您也可以将剩余值作为字符串 ($scope.remaining='BDEGHJ';) 进行跟踪。然后,您可以在下拉列表中使用 ng-change 指令,并使用简单的 string.replace 添加或删除值,而不是 $watching 每次更改。您需要跟踪先前选择的值,以便在切换时将它们放回列表中。

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 一起工作就像一个魅力!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-26
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2020-05-10
    • 2014-03-03
    相关资源
    最近更新 更多