【问题标题】:Angular with multiple selects that must have unique options selected具有多个选择的 Angular,必须选择唯一选项
【发布时间】:2016-11-09 05:43:27
【问题描述】:

我有一个角度页面,上面有动态数量的选择元素。每个 select 都将具有相同的选项集合,但一旦从中选择了一个选项,则应从所有后续 select 元素中删除该选项。

我发现了这个:http://jsfiddle.net/Zv5NE/63/,它完全按照我的意愿工作(当从一个选项中选择一个选项时,它会从其他选项中删除,然后如果相同的选项被更改,它会将先前选择的选项添加回其他人)。

问题是,这是使用硬编码数量的选择元素,并且还为每个选择元素使用硬编码过滤器......这对我的目的不起作用,因为正如我所说,我的用户将需要能够动态添加 n 个选择元素。

我已经尝试过创建自己的过滤器来适应这种情况,但我的角度非常绿色(角度为 1 btw)而且我已经碰壁了。

这是我尝试过的一个小sn-p。本质上,我只是尝试创建一个数组并将选定的项目添加到该数组,然后检查过滤器数组中的值(显然我必须添加一些逻辑来更改选项,但我真的不确定这是正确的方向):

        $scope.filter = function (item) {
            for (i = 0; i < $scope.names.length; i++) {
                if (item == $scope.names[i]) {
                    return false;
                }                        
            }
            return true;
        };

任何指导将不胜感激。

【问题讨论】:

  • 我没有看到任何理由特别说明您需要在您的情况下使用多个选择选项,因为您提到它具有相同的选项集合。这对我来说似乎是反模式,你正在努力尝试。您可以选择多个选项,即select multipleisteven.github.io/angular-multi-select/#/main。从用户角度来看,它更直观。
  • 我不能这样做,因为每个选择都是较大对象的一小部分(想想 HTML 中的表格行,其中选择只有一列)。从唯一的选择元素中选择选项后,该行将显示更多选项。

标签: javascript angularjs select


【解决方案1】:

我搁置了一段时间,但今天早上又回来了。我能够想出一个可行的解决方案。

这是我写的。可能不是最优雅的方式,但它适用于我的目的:

    <!DOCTYPE html>

<html ng-app="app">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AngularTest</title>
</head>
<body ng-controller="HellowWorldCtrl">
    <select ng-model="selectname0" ng-options="item as item.name for item in classes | customFilter:'selectname0':this">
        <option value="">- select -</option>
    </select>
    <div id="selectsDiv"></div>
    <br />
    <input type="button" value="Add Select" ng-click="addSelect()" ng-show="cnt < classes.length -1" />



    <script src="~/Scripts/angular.js"></script>
    <script type="text/javascript">

        var app = angular.module('app', []).controller('HellowWorldCtrl', function ($scope, $compile) {
            $scope.cnt = 0;
            $scope.selectsAdded = [];
            $scope.selectsAdded.push('selectname0');
            $scope.addSelect = function () {
                $scope.cnt++;
                $scope.selectsAdded.push('selectname' + $scope.cnt);
                var newSelect = $compile('<div><select ng-model="selectname' + $scope.cnt + '" ng-options="item as item.name for item in classes | customFilter:\'selectname' + $scope.cnt + '\':this"><option value="">- select -</option></select></div>')($scope);
                angular.element(document.getElementById('selectsDiv')).append(newSelect);
            };

            $scope.classes = [
              {
                  id: 1,
                  name: 'Biology 101',
                  courseid: '12345'
              },
              {
                  id: 2,
                  name: 'Chemistry 101',
                  courseid: '12374'
              },
              {
                  id: 3,
                  name: 'Psychology 101',
                  courseid: '32165'
              },
              {
                  id: 4,
                  name: 'Geology 101',
                  courseid: '78945'
              },
              {
                  id: 5,
                  name: 'Math 101',
                  courseid: '65478'
              }

            ];

        });

        app.filter('customFilter', function () {
            return function (items, which, scope) {
                var alreadySelectedCourses = [];
                var courses = [];
                for (i = 0; i < items.length; i++) { // loop over all of the items in the class array...cwc
                    for (j = 0; j < scope.selectsAdded.length; j++) { // loop over all of the selects added to the page...cwc
                        if (which == scope.selectsAdded[j]) { // check if the calling select is the same one in the loop...cwc
                            if (scope['selectname' + j] && scope['selectname' + j].id) { // check if the calling select has alraedy been selected...cwc
                                if (scope['selectname' + j].id == items[i].id) { // check if the selected value of the calling select is the same as the item in the iteration and add it to the return array if so...cwc
                                    courses.push(items[i]);
                                    alreadySelectedCourses.push(items[i]);
                                }
                            }
                        } else { // not the calling select so find out the value and don't add it to the return array...cwc
                            if ((scope['selectname' + j] && scope['selectname' + j].id)) { // other selects (not calling select) have values selected so add them to the alreadyselectedarray...cwc
                                if (scope['selectname' + j].id == items[i].id) {
                                    alreadySelectedCourses.push(items[i]);
                                }
                            }
                        }
                    }
                    if (alreadySelectedCourses.indexOf(items[i]) > -1) {
                        continue;
                    } else {
                        courses.push(items[i]);
                    }
                }
                return courses;
            }
        });
    </script>
</body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    相关资源
    最近更新 更多