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();
}
};
});