在angular.js中创建级联dropbox

creating a cascading dropbox in angular.js

本文关键字:级联 dropbox 创建 angular js      更新时间:2024-04-11

我有一个嵌套对象,我正试图将其变成级联选择框。

    "A": {
      "a1": 1,
      "a2": 2
    },
    "B": {
      "b1": {
        "b11": 111
      },
      "b2": {
        "b222": 222
      }
    }
  };

用户应该选择值,直到达到某个值。收集的深度未知。

例如-"B"->"b1"->"b11"->111。在这种情况下,我们有三个选择框。"A"->"a1"->1-只有两个。每个框都将在上一级别中选择一个值后出现。

我用一个模板进行了尝试(根据我的经验,这是实现递归的唯一方法)。我需要scope.value的最终值。

<script type="text/ng-template" id="cascading_combo.html">
    <h5> current </h5>
    <pre>{{current | json}}</pre>
    <select ng-model='value' ng-options="v as k for (k,v) in current"></select>
    <pre> type of {{value}} : {{angular.isObject(value)}}</pre>
    <span ng-if="angular.isObject(value)" ng-init='current=value' ng-include='"cascading_combo.html"'>
    </span>
</script>

这不起作用,部分原因是angular.isObject没有返回任何结果。

JSBIN playgorund。

棱角分明的新手,谢谢你的帮助。

不能在这样的表达式中调用angular.isObject()。Angular正在寻找的是父控制器范围内的函数$scope.angular.isObject()(就像value实际上是$scope.value一样)。

你能做的是:

selectCtrl中:

$scope.isObject = angular.isObject;

cascading_combo.html:中

<pre> type of {{value}} : {{isObject(value)}}</pre>
<span ng-if="isObject(value)" ng-init='current=value' ng-include='"cascading_combo.html"'>

问题:您遇到了一个无限循环。

如果value是一个对象,则会再次加载该模板。所有这些模板都存在于selectCtrl的同一范围内,因此当新模板被附加时,value仍然是一个对象,因此另一个模板被附加,依此类推…

为了防止这种情况,您必须在附加新模板时重置value。例如,你可以再次修改你的模板并这样做:

<select ng-init="value=undefined" ng-model="value" ng-options="k for (k,v) in current"></select>

请参阅此处查看最终结果。


更新

上面的例子不能以动态方式工作,因为模板一旦添加就无法删除。以下是一种使用ngRepeat和单个列表的非回溯方法:

HTML

<div ng-app="app" ng-controller="ctrl">
     <div recoursive-select="" ng-repeat="item in selected"></div>
</div>

JS

app = angular.module('app', []);
app.controller('ctrl', function($scope) {
    $scope.selected = [/** insert first element here **/];
});
app.directive('recoursiveSelect', function() {
    return {
        template: '<select ng-model="newSelected" ng-options="key for (key, value) in data"></select>',
        controller: function($scope) {
            // workaround to strip the $$hashKey of ngRepeat
            $scope.data = angular.fromJson(angular.toJson($scope.item));
            // watch for selecting a value
            $scope.$watch('newSelected', function(newSelected) {
                // watch is always called initially. do this to prevent infinite loop
                if (!newSelected) return;
                var nextIndex = $scope.$index + 1;
                // remove all "deeper" elements plus the one on this level
                while ($scope.selected.length > nextIndex) {
                    $scope.selected.pop()
                }
                // add the newly selected element on this level
                $scope.selected.push(newSelected);
            });
        }
    };
});

实时