ng-options,其中一个选择确定另一个的选项

时间:2014-07-18 16:32:48

标签: javascript angularjs angular-ui ng-options

我有两个下拉列表,我希望第二个下拉列表只包含与第一个中所选项目相关的选项。我可以做一些ng-change功能,但我试图让它只用于html中的代码,并且很接近但不完全。

我尝试了here找到的东西,但它不太合适。当没有选择Level 1时,它显示Level 2的所有选项而不是None,当选择Level 1时,它只显示Level 2的第一个有效选项。我想,如果a选择了级别1,它应该显示b,c,d,e作为级别2的选项,如果选择了z,它应该显示c,d,f,g作为级别2的选项。

这是我在plnkr中的代码:

http://plnkr.co/edit/DuCMjAUKTBiGJNQfhVbd?p=preview

这是我的javascript:

var app = angular.module('myApp', ['ui', 'ui.filters']);
app.controller('myController', function($scope){
  $scope.myFilters = [
    {level1:'a',level2:'b'},
    {level1:'a',level2:'c'},
    {level1:'a',level2:'d'},
    {level1:'a',level2:'e'},
    {level1:'z',level2:'c'},
    {level1:'z',level2:'d'},
    {level1:'z',level2:'f'},
    {level1:'z',level2:'g'},
    ];
});

这是我的HTML:

<body ng-app="myApp">
 <div ng-controller="myController">
  <form>
  Level 1:
  <select name="level1" ng-model="level1selection" ng-options="myFilter.level1 for myFilter in myFilters | unique:'level1'"></select>
  <br />

  Level 2:
  <select name="level2" ng-model="level2selection" ng-options="myFilter.level2 for myFilter in myFilters | filter:myFilter.level1=level1selection | unique:'level2'"></select>
  </form>
</div>

3 个答案:

答案 0 :(得分:0)

可能从模板中挂起所有这些,但表达式变得非常混乱。在一天结束时,我认为它实际上更多&#34;声明&#34;准确指出ngChange指令即将发生的事情。在这里看到Plunkr的工作: http://plnkr.co/edit/WJ91H0NmiRcOY6H5lpTE?p=preview

基本上,您所做的只是将数据结构更改为更像这样:

$scope.options = {
  'a': ['b', 'c', 'd', 'e'],
  'z': ['c', 'd', 'e', 'f']
};

您还可以通过许多其他方式执行此操作,此方法将起作用。例如,您的level1和level2列表可以是完全独立的结构。对于大多数具有嵌套选项列表的应用来说,这是非常典型的,因为每个选项都是数据库中的一些条目表或类似的。

然后你只需使用在用户选择第一个组合框中的选项时触发的ng-change:

$scope.level1Change = function() {
  $scope.level2 = $scope.options[$scope.level1selection];
}

这是一个额外的几行代码,当然,它仍然尊重AngularJS的所有原则,它清晰易懂......而且它实际上效率更高因为表达式更简单,并且不需要过滤器。如果您更改原始过滤器表达式以调用您自己的函数,并在其上放置console.log(),您会对它被调用的频率感到震惊。

Angular并不是一个很好的方法来判断它何时需要调用过滤器,所以它往往比你想象的要多得多。基本上任何触发摘要的东西都会触发这个,即使用户没有触及这些表单元素。

如果您真的想要摆脱这个回调,您可以在HTML模板中做同样的事情,如下所示:

<select name="level1" ng-model="level1selection"
        ng-options="level1 as level1 for (level1, level2) in options"
        ng-change="level2 = options[level1selection];"></select>

答案 1 :(得分:0)

我想出了一个小小的变化,通过改变它来使我的例子有效:

<select name="level2" ng-model="level2selection" ng-options="myFilter.level2 for myFilter in myFilters | filter:myFilter.level1=level1selection | unique:'level2'"></select>

到此:

<select name="level2" ng-model="level2selection" ng-options="myFilter.level2 for myFilter in myFilters | filter:myFilter.level1=level1selection.level1 | unique:'level2'"></select>

似乎选择的值是我“表”中的第一行,而不是显示的值。不确定是否有办法直接将ng-model设置为显示值?

答案 2 :(得分:0)

你只需改变

filter:myFilter.level1=level1selection

filter:{level1:level1selection.level1}

就是这样。

<form>
      Level 1:
      <select name="level1" ng-model="level1selection" ng-options="myFilter.level1 for myFilter in myFilters | unique:'level1'"></select>
      <br />
      Level 2:
      <select name="level2" ng-model="level2selection" 
         ng-options="myFilter.level2 for myFilter in myFilters | filter:{level1:level1selection.level1}"></select>
</form>