AngularJS - 多个下拉菜单
AngularJS - Multiple Dropdowns
我目前正在做一个项目,我有一个按钮,每次单击该按钮时都会添加一个下拉菜单。
单击该按钮不仅会显示下拉菜单,还会显示一个 "Remove item" 按钮,您可以在其中删除相应的已添加项目。
然后,如果您 select 从下拉菜单中选择一个选项,它将显示另一个包含更多选项的下拉菜单,具体取决于您在第一个下拉菜单中选择的内容。
您可以从下拉列表中选择两个选项,电影或游戏。
然后在第二个下拉菜单中应该会出现电影列表或游戏列表,具体取决于您 select编辑的内容。
您可以看到 HERE 当前 fiddle。
index.html:
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click = "addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click = "removeItem($index)">Remove item</button>
<select ng-model="category"
ng-change="changeCategory(category)"
ng-options="category as category for category in categoryTypes">
<option></option>
</select>
<select ng-show="movieSelected"
ng-model="movieType"
ng-options="movie as movie for movie in movieCategories">
<option></option>
</select>
<select ng-show="gameSelected"
ng-model="gameType"
ng-options="game as game for game in gameCategories">
<option></option>
</select>
</div>
</div>
app.js:
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', function ($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = { item : [] };
$scope.itemSet.item = [];
$scope.gameSelected = false;
$scope.movieSelected = false;
$scope.addNewItem = function () {
$scope.itemSet.item.push('');
};
$scope.removeItem = function (index) {
$scope.itemSet.item.splice(index, 1);
};
$scope.changeCategory = function(category) {
if(category == 'Movies') {
$scope.gameSelected = false;
$scope.movieSelected = true;
} else {
$scope.gameSelected = true;
$scope.movieSelected = false;
}
};
}]);
有些地方出了问题。没有特别的顺序:
例如,如果我添加了 3 个项目,然后想删除第一个,如果您一直按 "Remove Item" 按钮,它将删除第三个,然后是第二个,最后是第一个。
例如,如果我添加 3 个项目并且我从第一行的第一个下拉列表中 select "movies",它将显示所有其他下拉列表,并且可以从所有的电影列表,即使我没有从其他行中选择任何东西。
此外,如果你想添加,比方说,2 个项目,在第一个项目中选择 "movies",然后在第二个项目中选择 "games","extra" 下拉菜单将显示游戏列表,而不是每个案例的相应项目列表。
实际项目的工作方式与此类似,但有 4 个下拉菜单,信息来自数据库,但我想 Fiddle 应该足以理解并采取可能的解决方案实际项目。
如果有人能在这方面帮助我,我将不胜感激!
主要问题是您的控件绑定了 $scope 值,而不是您尝试操作的单个项目。第二个问题是您将每个新数组元素初始化为空字符串 '' 而不是对象 {}。
这会起作用:
index.html
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click = "addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click = "removeItem($index)">Remove item</button>
<select ng-model="item.category"
ng-change="changeCategory(item)"
ng-options="category as category for category in categoryTypes">
<option></option>
</select>
<select ng-show="item.movieSelected"
ng-model="movieType"
ng-options="movie as movie for movie in movieCategories">
<option></option>
</select>
<select ng-show="item.gameSelected"
ng-model="gameType"
ng-options="game as game for game in gameCategories">
<option></option>
</select>
</div>
</div>
app.js
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', function ($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = { item : [] };
$scope.itemSet.item = [];
$scope.gameSelected = false;
$scope.movieSelected = false;
$scope.addNewItem = function () {
$scope.itemSet.item.push({});
};
$scope.removeItem = function (index) {
$scope.itemSet.item.splice(index, 1);
};
$scope.changeCategory = function(item) {
if(item.category == 'Movies') {
item.gameSelected = false;
item.movieSelected = true;
} else {
item.gameSelected = true;
item.movieSelected = false;
}
};
}]);
已更新 fiddle:https://jsfiddle.net/5zwsdbr0/
您的 code
有一个 大 问题,即:您对 ngRepeat
中的所有项目都有相同的 ngModel
。
解决此问题后,您可以大大简化 code
。
你不需要使用ngChange
来知道category
是什么selected,你可以简单地使用ngSwitch
指令what fits在这种情况下很好。
看到了工作:
(function() {
'use strict';
angular
.module('myApp', [])
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['$scope'];
function testCtrl($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = {
item: []
};
$scope.addNewItem = function() {
$scope.itemSet.item.push({});
};
$scope.removeItem = function(index) {
$scope.itemSet.item.splice(index, 1);
};
}
})();
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click="addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click="removeItem($index)">Remove item</button>
<select ng-model="item.category"
ng-options="category for category in categoryTypes">
<option value hidden>Select a category</option>
</select>
<span ng-switch="item.category">
<select ng-switch-when="Movies"
ng-model="item.movie"
ng-options="movie for movie in movieCategories">
<option value hidden>Select a movie</option>
</select>
<select ng-switch-when="Games"
ng-model="item.game"
ng-options="game for game in gameCategories">
<option value hidden>Select a game</option>
</select>
</span>
</div>
<pre ng-bind="itemSet.item | json"></pre>
</div>
</body>
</html>
我目前正在做一个项目,我有一个按钮,每次单击该按钮时都会添加一个下拉菜单。
单击该按钮不仅会显示下拉菜单,还会显示一个 "Remove item" 按钮,您可以在其中删除相应的已添加项目。
然后,如果您 select 从下拉菜单中选择一个选项,它将显示另一个包含更多选项的下拉菜单,具体取决于您在第一个下拉菜单中选择的内容。
您可以从下拉列表中选择两个选项,电影或游戏。
然后在第二个下拉菜单中应该会出现电影列表或游戏列表,具体取决于您 select编辑的内容。
您可以看到 HERE 当前 fiddle。
index.html:
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click = "addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click = "removeItem($index)">Remove item</button>
<select ng-model="category"
ng-change="changeCategory(category)"
ng-options="category as category for category in categoryTypes">
<option></option>
</select>
<select ng-show="movieSelected"
ng-model="movieType"
ng-options="movie as movie for movie in movieCategories">
<option></option>
</select>
<select ng-show="gameSelected"
ng-model="gameType"
ng-options="game as game for game in gameCategories">
<option></option>
</select>
</div>
</div>
app.js:
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', function ($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = { item : [] };
$scope.itemSet.item = [];
$scope.gameSelected = false;
$scope.movieSelected = false;
$scope.addNewItem = function () {
$scope.itemSet.item.push('');
};
$scope.removeItem = function (index) {
$scope.itemSet.item.splice(index, 1);
};
$scope.changeCategory = function(category) {
if(category == 'Movies') {
$scope.gameSelected = false;
$scope.movieSelected = true;
} else {
$scope.gameSelected = true;
$scope.movieSelected = false;
}
};
}]);
有些地方出了问题。没有特别的顺序:
例如,如果我添加了 3 个项目,然后想删除第一个,如果您一直按 "Remove Item" 按钮,它将删除第三个,然后是第二个,最后是第一个。
例如,如果我添加 3 个项目并且我从第一行的第一个下拉列表中 select "movies",它将显示所有其他下拉列表,并且可以从所有的电影列表,即使我没有从其他行中选择任何东西。
此外,如果你想添加,比方说,2 个项目,在第一个项目中选择 "movies",然后在第二个项目中选择 "games","extra" 下拉菜单将显示游戏列表,而不是每个案例的相应项目列表。
实际项目的工作方式与此类似,但有 4 个下拉菜单,信息来自数据库,但我想 Fiddle 应该足以理解并采取可能的解决方案实际项目。
如果有人能在这方面帮助我,我将不胜感激!
主要问题是您的控件绑定了 $scope 值,而不是您尝试操作的单个项目。第二个问题是您将每个新数组元素初始化为空字符串 '' 而不是对象 {}。
这会起作用:
index.html
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click = "addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click = "removeItem($index)">Remove item</button>
<select ng-model="item.category"
ng-change="changeCategory(item)"
ng-options="category as category for category in categoryTypes">
<option></option>
</select>
<select ng-show="item.movieSelected"
ng-model="movieType"
ng-options="movie as movie for movie in movieCategories">
<option></option>
</select>
<select ng-show="item.gameSelected"
ng-model="gameType"
ng-options="game as game for game in gameCategories">
<option></option>
</select>
</div>
</div>
app.js
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', function ($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = { item : [] };
$scope.itemSet.item = [];
$scope.gameSelected = false;
$scope.movieSelected = false;
$scope.addNewItem = function () {
$scope.itemSet.item.push({});
};
$scope.removeItem = function (index) {
$scope.itemSet.item.splice(index, 1);
};
$scope.changeCategory = function(item) {
if(item.category == 'Movies') {
item.gameSelected = false;
item.movieSelected = true;
} else {
item.gameSelected = true;
item.movieSelected = false;
}
};
}]);
已更新 fiddle:https://jsfiddle.net/5zwsdbr0/
您的 code
有一个 大 问题,即:您对 ngRepeat
中的所有项目都有相同的 ngModel
。
解决此问题后,您可以大大简化 code
。
你不需要使用ngChange
来知道category
是什么selected,你可以简单地使用ngSwitch
指令what fits在这种情况下很好。
看到了工作:
(function() {
'use strict';
angular
.module('myApp', [])
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['$scope'];
function testCtrl($scope) {
$scope.categoryTypes = ['Movies', 'Games'];
$scope.gameCategories = ['RPG', 'Sports'];
$scope.movieCategories = ['Action', 'SciFi'];
$scope.itemSet = {
item: []
};
$scope.addNewItem = function() {
$scope.itemSet.item.push({});
};
$scope.removeItem = function(index) {
$scope.itemSet.item.splice(index, 1);
};
}
})();
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="testCtrl">
<button ng-click="addNewItem()">Add new Item</button>
<div ng-repeat="item in itemSet.item track by $index">
<button ng-click="removeItem($index)">Remove item</button>
<select ng-model="item.category"
ng-options="category for category in categoryTypes">
<option value hidden>Select a category</option>
</select>
<span ng-switch="item.category">
<select ng-switch-when="Movies"
ng-model="item.movie"
ng-options="movie for movie in movieCategories">
<option value hidden>Select a movie</option>
</select>
<select ng-switch-when="Games"
ng-model="item.game"
ng-options="game for game in gameCategories">
<option value hidden>Select a game</option>
</select>
</span>
</div>
<pre ng-bind="itemSet.item | json"></pre>
</div>
</body>
</html>