具有多个选择的Angular,必须选择唯一选项

时间:2016-10-28 15:15:03

标签: javascript angularjs select

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

我发现了这个:http://jsfiddle.net/Zv5NE/63/,它的确如何运作(当从一个选项中选择一个选项时,它会从其他选项中删除,然后如果相同的选择被更改,它将之前选择的选项添加回其他选项。

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

我已经做了一些尝试创建我自己的过滤器以适应这一点,但我超级绿色到角度(角度1 btw),我已经撞到了墙。

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

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

任何指导都将不胜感激。

1 个答案:

答案 0 :(得分:0)

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

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

    <!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>