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>