我有一个嵌套对象,我试图将其变成级联选择框。
"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
没有返回任何结果。
Angular newbi,感谢任何帮助。
答案 0 :(得分:2)
您无法在类似的表达式中调用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>
有关最终结果,请参阅here。
上面的示例不能以动态方式工作,因为一旦添加了模板,就无法删除它。以下是使用ngRepeat
和单个列表的非重复方法:
<div ng-app="app" ng-controller="ctrl">
<div recoursive-select="" ng-repeat="item in selected"></div>
</div>
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);
});
}
};
});