AngularJS多个选择元素不能具有相同的值

时间:2021-05-13 22:33:50

I'm quite new to AngularJS and I'm trying to define 4 seperate select elements usign element directives.

我是AngularJS的新手,我正在尝试定义4个单独的选择元素usign元素指令。

app.directive('playerselect', function() {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'templates/directives/player-select.html',
    }
});

<select ng-options="player.full_name for player in players">
    <option value="" selected disabled>Kies een speler</option>
</select>

When a user selects an option in one of the select elements I want the other select elements to be updated, so that the selected option gets disabled in all other select elements. Basically, I want to make sure that each option can get chosen only once.

当用户选择其中一个选择元素中的选项时,我希望更新其他选择元素,以便在所有其他选择元素中禁用所选选项。基本上,我想确保每个选项只能选择一次。

Any ideas on how to do this?

关于如何做到这一点的任何想法?

2 个解决方案

#1


4  

I would do it like this:

我会这样做:

directive

指示

app.directive('playerSelect', function() {
    return {
        templateUrl: ...
        scope: {
            players: '=',
            selectedPlayer: '=',
            selectedPlayers: '=',
        },
        controller: function($scope) {
            $scope.isDisabled = function(player) {
                return $scope.selectedPlayers.indexOf(player) > -1 &&
                       player !== $scope.selectedPlayer)
            };
        },
    }
});

directive template

指令模板

<select ng-model="selectedPlayer">
  <option ng-repeat="player in players" ng-disabled="isDisabled(player)">{{player}}</option>
</select>

controller

调节器

app.controller('PlayerController', function($scope) {
    $scope.players = ...
    $scope.selectedPlayers = [
        $scope.player1,
        $scope.player2,
        $scope.player3,
        $scope.player4,
    ];
});

controller template

控制器模板

<div ng-controller="PlayerController">
  <player-select players="players" selected-players="selectedPlayers" selected-player="player1"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player2"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player3"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player4"></player-select>
</div>

#2


1  

Check this jsFiddle for see it in action.

检查这个jsFiddle以查看它的实际效果。

I would recommend you an use of directive two way data binding and ngModelController.

我建议你使用指令双向数据绑定和ngModelController。

So in your html :

所以在你的HTML中:

<player-select players="players" ng-model="select1"></player-select>
<player-select players="players" ng-model="select2"></player-select>
<player-select players="players" ng-model="select3"></player-select>

In your controller :

在你的控制器中:

$scope.players = [{
    name: 'foo'
}, {
    name: 'bar'
}, {
    name: 'baz'
}];

And the directive, using scope.$watch for update each list :

和指令一样,使用范围。$ watch更新每个列表:

angular.module('fiddleApp').directive('playerSelect', function ($rootScope) {
    return {
        restrict: 'E',
        require: 'ngModel',
        scope: {
            players: '='
        },
        template: '<select ng-model="selected" ng-options="player.name for player in     playersCopy"></select>',
        link: function (scope, el, attrs, ngModel) {

            function update() {
                scope.playersCopy = angular.copy(scope.players);
                if (scope.selected) {
                    scope.playersCopy.push(scope.selected);
                }
            }

            scope.$watch('selected', function (newValue, oldValue) {
                if (newValue) {
                    scope.players.splice(scope.players.map(function (a) {
                        return a.name
                    }).indexOf(newValue.name), 1);

                    if (oldValue) { scope.players.push(oldValue); }

                    ngModel.$setViewValue(scope.selected);
                    $rootScope.$broadcast('playersUpdate');
                }
            });

            scope.$on('playersUpdate', function () {
                update();
            });

            update();
        }
    };
});

#1


4  

I would do it like this:

我会这样做:

directive

指示

app.directive('playerSelect', function() {
    return {
        templateUrl: ...
        scope: {
            players: '=',
            selectedPlayer: '=',
            selectedPlayers: '=',
        },
        controller: function($scope) {
            $scope.isDisabled = function(player) {
                return $scope.selectedPlayers.indexOf(player) > -1 &&
                       player !== $scope.selectedPlayer)
            };
        },
    }
});

directive template

指令模板

<select ng-model="selectedPlayer">
  <option ng-repeat="player in players" ng-disabled="isDisabled(player)">{{player}}</option>
</select>

controller

调节器

app.controller('PlayerController', function($scope) {
    $scope.players = ...
    $scope.selectedPlayers = [
        $scope.player1,
        $scope.player2,
        $scope.player3,
        $scope.player4,
    ];
});

controller template

控制器模板

<div ng-controller="PlayerController">
  <player-select players="players" selected-players="selectedPlayers" selected-player="player1"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player2"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player3"></player-select>
  <player-select players="players" selected-players="selectedPlayers" selected-player="player4"></player-select>
</div>

#2


1  

Check this jsFiddle for see it in action.

检查这个jsFiddle以查看它的实际效果。

I would recommend you an use of directive two way data binding and ngModelController.

我建议你使用指令双向数据绑定和ngModelController。

So in your html :

所以在你的HTML中:

<player-select players="players" ng-model="select1"></player-select>
<player-select players="players" ng-model="select2"></player-select>
<player-select players="players" ng-model="select3"></player-select>

In your controller :

在你的控制器中:

$scope.players = [{
    name: 'foo'
}, {
    name: 'bar'
}, {
    name: 'baz'
}];

And the directive, using scope.$watch for update each list :

和指令一样,使用范围。$ watch更新每个列表:

angular.module('fiddleApp').directive('playerSelect', function ($rootScope) {
    return {
        restrict: 'E',
        require: 'ngModel',
        scope: {
            players: '='
        },
        template: '<select ng-model="selected" ng-options="player.name for player in     playersCopy"></select>',
        link: function (scope, el, attrs, ngModel) {

            function update() {
                scope.playersCopy = angular.copy(scope.players);
                if (scope.selected) {
                    scope.playersCopy.push(scope.selected);
                }
            }

            scope.$watch('selected', function (newValue, oldValue) {
                if (newValue) {
                    scope.players.splice(scope.players.map(function (a) {
                        return a.name
                    }).indexOf(newValue.name), 1);

                    if (oldValue) { scope.players.push(oldValue); }

                    ngModel.$setViewValue(scope.selected);
                    $rootScope.$broadcast('playersUpdate');
                }
            });

            scope.$on('playersUpdate', function () {
                update();
            });

            update();
        }
    };
});