Hacking with Angular: 玩轉ngOptions指令
首先說說為什么要詳細的了解一下這個指令,因為在工作中總是遇到關于下拉選項的一些操作,但是又常常會出現一些問題;基本會遇到下面一些問題:
-
關于下拉框使用 ng-repeat 或者 ng-options 指令的區別
-
關于下拉框的 默認選項 如何設置
-
關于下拉框選項的 model值 如何綁定
-
關于下拉框的 禁用選項 問題
-
關于下拉框的 分組 問題
-
關于下拉框的 排序 問題
下面我們就來好好的研究一下 ng-options ,下面的部分就是關于上面問題的解決方案。
下面的部分沒有太按照上面的問題的順序,但是他們的解決方法都在里面有提及。
下拉框的默認選項一般是可以通過使用 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