防止多个选择具有相同的值

时间:2016-12-31 10:54:56

标签: javascript angularjs ng-repeat ng-options angular-filters

它应该做什么

我想阻止用户在具有相同选项的多个<select>中选择相同选项的两倍。

正在做什么

在第一个下拉列表中选择一个值时,第二个下拉列表将不会显示该选项(很好)。但是当在第二个下拉列表中选择一个值(并且第一个下拉列表已经有一个值)时,它将删除所有选择。我最终选择了[null, null]

我错过了什么吗?

JSFiddle

var app = angular.module('App', []);

app.controller('AppController', function($scope) {
  $scope.selected = [];
  $scope.array = [{
    id: 0,
    title: 'Option0'
  }, {
    id: 1,
    title: 'Option1'
  }, {
    id: 2,
    title: 'Option2'
  }, {
    id: 3,
    title: 'Option3'
  }];
});

app.filter('arrayFilter', function() {
  return (arr, remove, keep) => {
    return arr.filter((item) => {
      for (var i in remove) {
        if (remove[i] == item.id) {
          // If checking current selected, return true
          if (i == keep) {
            return true;
          }
          // Otherwise, current item is selected, return false
          return false;
        }
      }
      return true;
    });
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>

<div ng-app="App" ng-controller="AppController">
  <select ng-model="selected[0]" ng-options="option.id as option.title for option in array | arrayFilter:selected:0 track by option.id"></select>
  <select ng-model="selected[1]" ng-options="option.id as option.title for option in array | arrayFilter:selected:1 track by option.id"></select>
  {{ selected }}
</div>

更多问题

对于这种行为,我应该ng-repeat使用ng-hide而不是ng-options使用filter吗?

在这种情况下,最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

我终于找到了一种方法,可以通过一些改变来实现它:

  • 我必须将arrayFilter更改为返回truefalse的过滤器,以显示或隐藏该选项。 HTML中的语法从option in array | arrayFilter更改为option in array | filter:arrayFilter
  • 我必须删除track by option.id

我认为问题主要来自于旧过滤器返回一个新数组,使ng-model失去对所选元素的引用。

JSFiddle

&#13;
&#13;
var app = angular.module('App', []);

app.controller('AppController', function($scope) {
  $scope.selected = [];
  $scope.array = [{
    id: 0,
    title: 'Option0'
  }, {
    id: 1,
    title: 'Option1'
  }, {
    id: 2,
    title: 'Option2'
  }, {
    id: 3,
    title: 'Option3'
  }];
  $scope.arrayFilter = function(selectionArray, position) {
    return function(item, index) {
      return selectionArray.indexOf(item.id) == -1 || item.id == selectionArray[position];
    }
  }
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>

<div ng-app="App" ng-controller="AppController">
  <select ng-model="selected[0]" ng-options="option.id as option.title for option in array | filter:arrayFilter(selected, 0)"></select>
  <select ng-model="selected[1]" ng-options="option.id as option.title for option in array | filter:arrayFilter(selected, 1)"></select>
  {{ selected }}
</div>
&#13;
&#13;
&#13;