角度下拉树结构

时间:2016-05-04 18:25:31

标签: javascript html angularjs dropdown

我有这个工作的jsfiddle:working fiddle for second level

我将第一个下拉列表中的品牌和第二个下拉列表中的模型分配给ng-repeat创建的每辆汽车。这很好。

但是我必须添加第三级(类型),如这个不起作用的jsfiddle所示:not working fiddle for third level

我知道问题所在,但我不知道如何修复它。 这是未定义的:

$scope.cars[index].model.model

有什么建议吗?

谢谢。

3 个答案:

答案 0 :(得分:0)

格式化JSON对象的方式很难阅读,也不直观。我建议将它格式化,以便您可以通过cars.brands[0].models[0].types[0]轻松进入汽车选择。这样,您可以毫不费力地使用ng-options。见工作小提琴:https://jsfiddle.net/udr9dksa/1/

var app = angular.module("app", []);
app.controller("MainCtrl", ["$scope",
    function($scope) {
    
    	$scope.selectedBrand = {};
        $scope.selectedModel = {};
        $scope.selectedType = {};
        
        $scope.cars = {
            brands: [{
                id: 1,
                name: "audi",
                models: [{
                    id: 1,
                    name: 'audiA',
                    types: [{
                        id: 1,
                        name: 'type audi A1'
                    }, {
                        id: 2,
                        name: 'type audi A2'
                    }]
                }, {
                    id: 2,
                    name: 'audiB',
                    types: [{
                        id: 1,
                        name: 'type audi B1'
                    }, {
                        id: 2,
                        name: 'type audi B2'
                    }]
                }]
            }, {
                id: 2,
                name: "bmw",
                models: [{
                    id: 1,
                    name: 'bmwA',
                    types: [{
                        id: 1,
                        name: 'type bmw A1'
                    }, {
                        id: 2,
                        name: 'type bmw A2'
                    }]
                }, {
                    id: 1,
                    name: 'bmwB',
                    types: [{
                        id: 1,
                        name: 'type bmw B1'
                    }, {
                        id: 2,
                        name: 'type bmw B2'
                    }]
                }]
            }]
        };
    }
]);
<div ng-app="app" ng-controller="MainCtrl">
  <h4>Select a brand</h4>
  <select ng-model="selectedBrand" ng-options="brand as brand.name for brand in cars.brands">
  </select>
  
  <h4>Select a model</h4>
  <select ng-model="selectedModel" ng-options="model as model.name for model in selectedBrand.models">
  </select>
  
  <h4>Select a type</h4>
  <select ng-model="selectedType" ng-options="type as type.name for type in selectedModel.types">
  </select>
  
  <h3>You have selected</h3>
  <pre>{{selectedType | json}}</pre>
  
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>

答案 1 :(得分:0)

我会稍微更改您的数据结构,因此您不必对ng-change处理程序执行任何操作。

向品牌模型添加eveything,然后您就可以轻松使用ng-options。如果您正在使用MongooseMongoDB,则可以使用嵌入式文档作为模型,并可能为该类型标准化数据(仅存储来自types集合的索引)。 (在演示中,所有内容都嵌入到品牌中,以使演示更容易理解。)

请查看下面的演示或fiddle

&#13;
&#13;
angular.module('demoApp', [])
  .controller('mainController', MainController);

function MainController($window) {
  var vm = this;
  vm.show = function(car) {
    if (!car.brand || !car.model || !car.type) return; // all fields required

    $window.alert('Selected brand ' + car.brand.name + ' - model: ' +
      car.model.name + ' - type: ' + car.type.name);
  };
  vm.cars = [{
    id: 0,
    name: 'car 1'
  }, {
    id: 1,
    name: 'car 2'
  }, {
    id: 2,
    name: 'car 3'
  }];

  vm.brands = [{
    id: 0,
    name: 'Audi',
    models: [{
      id: 0,
      name: 'Audi 1',
      types: [{
        id: 0,
        name: 'cabrio'
      }, {
        id: 1,
        name: 'combi'
      }]
    }, {
      id: 1,
      name: 'Audi 2',
      types: [{
        id: 0,
        name: 'limosine'
      }, {
        id: 1,
        name: 'van'
      }]
    }, {
      id: 2,
      name: 'Audi 3',
      types: [{
        id: 0,
        name: 'mini van'
      }, {
        id: 1,
        name: 'combi'
      }]
    }]
  }, {
    id: 1,
    name: 'BMW',
    models: [{
      id: 0,
      name: 'BMW 1',
      types: [{
        id: 0,
        name: 'cabrio'
      }, {
        id: 1,
        name: 'combi'
      }]
    }, {
      id: 1,
      name: 'BMW 2',
      types: [{
        id: 0,
        name: 'limosine'
      }, {
        id: 1,
        name: 'van'
      }]
    }, {
      id: 2,
      name: 'BMW 3',
      types: [{
        id: 0,
        name: 'mini van'
      }, {
        id: 1,
        name: 'combi'
      }]
    }]
  }];
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
  <div ng-repeat="car in mainCtrl.cars">
    {{car.name}}
    <label>brand</label>
    <select ng-model="car.brand" ng-options="brand as brand.name for brand in mainCtrl.brands">
    </select>
    <label>model</label>
    <select ng-model="car.model" ng-options="model as model.name for model in car.brand.models">
    </select>
    <label>type</label>
    <select ng-model="car.type" ng-options="type as type.name for type in car.model.types">
    </select>
    <button ng-click="mainCtrl.show(car)">
      show
    </button>
  </div>

  <h2>
    current cars model (debugging):
    </h2>
  <pre>
        {{mainCtrl.cars | json : 2}}
    </pre>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如果不进行更改,您的数据结构需要将DOM和您的功能更改为完美的工作。

仅更改第二个和第三个选择标记。第二个ng-change函数调用。喜欢:ng-change="loadTypes($index, brand.model.model)"。对于第三个使用cars[$index].models[$index].types而不是cars[$index].models.types意味着在特定模型中分配数组并相关更改控制器功能。

可以尝试:

HTML:

<label>model</label>
    <select ng-model="brand.model" ng-options="caras car.model for car in cars[$index].models"  ng-change="loadTypes($index, brand.model.model)"><option value="">select</option></select>

<label>type</label>
    <select ng-model="car.brand.model.type" ng-options="car as car.type for car in cars[$index].models[$index].types"><option value="">select</option></select>

你的功能应该是:

$scope.loadModels = function(index){
    $scope.cars[index].models = $scope[$scope.cars[index].brand.name];
}
$scope.loadTypes = function(index, brandModel){
    $scope.cars[index].models[index].types = $scope[brandModel];
}