首先说说为什么要详细的了解一下这个指令,因为在工作中总是遇到关于下拉选项的一些操作,但是又常常会出现一些问题;基本会遇到下面一些问题:
关于下拉框使用ng-repeat
或者ng-options
指令的区别
关于下拉框的默认选项如何设置
关于下拉框选项的model值如何绑定
关于下拉框的禁用选项问题
关于下拉框的分组问题
关于下拉框的排序问题
下面我们就来好好的研究一下ng-options
,下面的部分就是关于上面问题的解决方案。
关于下面的例子详见demo,原文链接
下面的部分没有太按照上面的问题的顺序,但是他们的解决方法都在里面有提及。
下拉框的默认选项一般是可以通过使用
ng-init
指令或者在控制器中对select
的model
值进行赋值来达到这个目的的。
关于使用ng-repeat
还是ng-options
的选择,当我们的下拉列表循环的只是一些简单的字符串或者数字的时候,使用这两个指令都是可以的;但是当我们下拉列表循环的是一些比较复杂的数据并且还有一些附带的其它要求的时候,我们应该使用ng-options
。
使用select
结合ng-repeat
指令组成一个含有默认值的下拉列表。
HTML部分
<select ng-init="vm.item1 = vm.items1[0]"
ng-model="vm.item1">
<option ng-selected="v == vm.items1[0]"
value="{{v}}"
ng-repeat="v in vm.items1">
{{v}}
option>
select>
JavaScript部分
vm.items1 = [
'选项一',
'选项二',
'选项三'
];
我们使用ng-repeat
指令对下拉列表的值进行循环,然后使用ng-init
对select
的model
进行初始化。
使用ng-options
达到和上面一样的效果
HTML部分
<select ng-model="vm.item2"
ng-init="vm.item2 = vm.items2[0]"
ng-options="v for v in vm.items2">
select>
JavaScript部分
vm.items2 = [1,2,3];
下面的部分具体的讲解ng-options
指令后面使用的复杂的表达式,还需要注意的是,我们使用的是数组作为下拉列表的输出,当然也可以使用对象,详情可以参考官网
select as label for value in array
首先说明一下上面的表达式中每一项表示的是什么;array
表示的是我们要进行循环的对象数组,value
表示这个数组中的单独一项,也就是一个单独的对象,select
和label
都是对象中的某一个属性,其中select
还可以表示整个对象;label
表示的是下拉框中的显示的选项,select
表示下拉框中选中某一个label
之后下拉框的model
的值。通俗一点说就是,label
只是下拉框中表现出来让你选择的选项,而select
是你选中那个选项之后,下拉列表的值
HTML部分
<select ng-init="vm.item3 = vm.items3[0].value"
ng-options="v.value as v.name for v in vm.items3"
ng-model="vm.item3">
select>
JavaScript部分
vm.items3 = [
{name: '选项一', value: 1},
{name: '选项二', value: 2},
{name: '选项三', value: 3}
];
解释一下上面的一些内容,其中ng-model="vm.item3"
指定了这个下拉框的model
值,我们使用ng-init
进行下拉框的初始化ng-init="vm.item3 = vm.items3[0].value"
,关于ng-options="v.value as v.name for v in vm.items3"
我们来看一下,其中v
表示数组中的单个对象,as
左边的值是我们的下拉框选中时的值,as
右边的值是下拉框表面表示选择项。在这个例子中,我们会看到下拉框给我们的选项是选项一
,选项二
,选项三
,但是当我们选中选项一
的时候实际上下拉框的值是1
也就是v.value
label group by group for value in array
group by group
的解释,其中前面的group by
是固定的,后面的group
使我们分组的依据。
HTML部分
<select ng-init="vm.item4 = vm.items4[0]"
ng-options="v.name group by v.group for v in vm.items4"
ng-model="vm.item4">
select>
JavaScript部分
vm.items4 = [
{name: '选项一', value: 1, group: 'A'},
{name: '选项二', value: 2, group: 'A'},
{name: '选项三', value: 3, group: 'A'},
{name: '选项四', value: 4, group: 'B'},
{name: '选项五', value: 5, group: 'B'},
{name: '选项六', value: 6, group: 'C'},
{name: '选项七', value: 7, group: 'C'}
];
页面中的表现如下图:
关于上面代码的一些解释,可以从上图看到,只要我们把分组的信息写好,angular
会帮助我们处理好分组的事情。
select as label disable when disable for value in array
disabled when disabled
,disabled when
是固定的语句,后面的disabled
是一个条件,如果条件是true
的话,那么这一项是不可以被选中的。
HTML部分
<select ng-init="vm.item5 = vm.items5[0].value"
ng-options="v.value as v.name disable when v.show for v in vm.items5"
ng-model="vm.item5">
select>
JavaScript部分
vm.items5 = [
{name: '选项一', value: 1},
{name: '选项二', value: 2, show: true},
{name: '选项三', value: 3},
{name: '选项四', value: 4, show: true},
{name: '选项五', value: 5}
];
label disable when disable for value in array
HTML部分
<select ng-init="vm.item6 = vm.items6[0]"
ng-options="v.name disable when v.show for v in vm.items6"
ng-model="vm.item6">
select>
JavaScript部分
vm.items6 = [
{name: '选项一', value: 1},
{name: '选项二', value: 2, show: true},
{name: '选项三', value: 3},
{name: '选项四', value: 4, show: true},
{name: '选项五', value: 5}
];
这个例子和上面的很相似,但是还是有一些区别的;这个例子的下拉框的model
值是一个对象,上面那个例子的下拉框的model
只是一个数字;从哪里可以看出来呢?因为两个ng-options
指令后面的表达式是不一样的,如果表达式中使用了as
关键字的话那么as
左边的表达式的值就是我们的下拉框的model
值,如果不使用的话,默认的就是我们数组中的某一项的值,在此处是一个对象。
label for value in array track by trackexpr
track by
是用来识别数组中的每个对象的,当这个数组再次被重新创建或者更新的时候的时候,已经选择的选项会被保留下来,也就是说,会保留每一项当时选择的状态。
HTML部分(未使用track by)
<select multiple
ng-init="vm.item7 = []"
ng-options="v.name for v in vm.items7"
ng-model="vm.item7">
select>
JavaScript部分(未使用track by)
vm.items7 = [
{name: '选项一', value: 1, id: 1},
{name: '选项二', value: 2, id: 2},
{name: '选项三', value: 3, id: 3},
{name: '选项四', value: 4, id: 4},
{name: '选项五', value: 5, id: 5}
];
JavaScript部分,公用的函数changeItems
部分
function changeItems() {
vm.items7 = [
{name: '选项一', value: 1, id: 1},
{name: '选项二', value: 2, id: 2},
{name: '选项三', value: 3, id: 3},
{name: '选项四', value: 4, id: 4},
{name: '选项五', value: 5, id: 5},
{name: '选项6', value: 6, id: 6}
];
vm.items8 = [
{name: '选项一', value: 1, id: 1},
{name: '选项二', value: 2, id: 2},
{name: '选项三', value: 3, id: 3},
{name: '选项四', value: 4, id: 4},
{name: '选项五', value: 5, id: 5},
{name: '选项6', value: 6, id: 6}
];
}
HTML部分
<select multiple
ng-init="vm.item8 = []"
ng-options="v.name for v in vm.items8 track by v.id"
ng-model="vm.item8">
select>
JavaScript部分
vm.items8 = [
{name: '选项一', value: 1, id: 1},
{name: '选项二', value: 2, id: 2},
{name: '选项三', value: 3, id: 3},
{name: '选项四', value: 4, id: 4},
{name: '选项五', value: 5, id: 5}
];
我们使用了下拉框的多选模式,这样就可以更清楚地看到我们说的为什么要使用track by
这个关键字的原因,在demo7中,我们没有使用track by
,我们将demo7下拉框的model
值初始化为一个数组,并且有一个辅助的函数changeItems
,模拟下拉框的选项变化;当我们选中一些选项后,点击更新按钮,会发现之前的选择已经被清零了;当是当我们使用了track by
之后,就像demo8中的示例那样,当我们选中了一些选项之后,再次点击更新按钮,会发现之前选择的选项依旧还是存在的。
label for value in array | orderBy : expr track by trackexpr
我们也可以在后面的表达式语句中使用orderBy
过滤器,使用过滤器的好处是,让下拉框的选项按照我们的要求进行进行排列,让我们使用起来更加方便。
HTML部分
<select ng-init="vm.item9 = vm.items9[vm.items9.length - 1]"
ng-options="v.name for v in vm.items9 | orderBy: ['value'] track by v.id"
ng-model="vm.item9">
select>
JavaScript部分
vm.items9 = [
{name: '选项一', value: 5, id: 1},
{name: '选项二', value: 4, id: 2},
{name: '选项三', value: 3, id: 3},
{name: '选项四', value: 2, id: 4},
{name: '选项五', value: 1, id: 5}
];
首先我们的数据部分和上面的不一样,我们将数据中的value
部分进行了倒序,然后又在表达式中使用orderBy
过滤器,并且按照value
值进行排序;关于orderBy
过滤器的使用方法可以参考官网。还要注意的是,我们也给这个下拉框的model
初始化了一个值,不然这个下拉框会有一个空白的选项,给用户的的体验很不好;当然我们也是根据数据的特征使用了ng-init="vm.item9 = vm.items9[vm.items9.length - 1]"
进行初始化。
关于下拉框要循环的是对象的情况基本上和上面的差不多,大家可以自行看官网上的说明,好了就先到这里了。
转自:https://segmentfault.com/a/1190000005342175