前兩篇都是說如果 Model 是陣列時如何使用 ng-options 來產生下拉選單的選項,今天則是要介紹若 Model 是個類似字典物件時的做法。
一樣是先準備好 Controller 及 Model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var SelectCtrl = function($scope) { $scope.onepiece = { '船長': { name: '蒙其·D·魯夫', age: 19, skills: ['橡膠槍', '橡膠火箭砲', '換檔', '霸氣'] } // 略... ,'音樂家': { name: '布魯克', age: 90, skills: ['催眠曲·輪舞', '鼻唄三丁·矢筈斬', '冰凍劍', '哼歌·吹雪斬'] } }; }; |
現在我們的 onepiece 就不再是陣列囉,現在它是一個基本的物件。其中像是 '船長'、'音樂家' 這些都是物件的屬性,同時也是字典物件所謂的 key。而每一個屬性(key)所對應的就是值(value)了。
我們的 View 一樣就是一個下拉選單再加一個 div:
1 2 3 4 5 6 7 | <div class="alert alert-info"> <select ng-model="role"> <option value="">--請選擇角色--</option> </select> <div ng-show="role!=null">選擇的是:{{ role }}</div> </div> |
Select 下拉選單一樣是綁定到 role 上,然後 div 的顯示與否是依 role 的值是否為 null 來決定的。
接下來就讓我們來看看 ng-options 對於物件的 4 種不同用法吧。
label for (key , value) in object
1 2 3 | <select ng-model="role1" ng-options="member.name for (title, member) in onepiece"> <option value="">--請選擇角色--</option> </select> |
因為在 onepiece 中的物件(或屬性)是由 (key, value) 組合而成的,所以當取出時,基本上就會是包含 (key, value)。接下來就可以決定用來顯示在選單上的文字內容是從那邊來的了,像這邊是從 member.name 來的,然後點選到某個選項後的值就是一個 member 物件。
那既然選到後的值是個物件,所以我們就先把 View 調整一下:
1 | <div ng-show="role!=null">選擇的是:{{ role.name + '(' + role.age + ')' }}</div> |
再來看下拉選單展開後的樣式:
當選擇到某個項目時:
預設選擇後得到的會是相對應的物件,若想指定值的話,則可以再利用 select 來指定。
select as label for (key , value) in object
1 2 3 | <select ng-model="role" ng-options="member.name as (title + '-' + member.name + '(' + member.age + ')') for (title, member) in onepiece"> <option value="">--請選擇角色--</option> </select> |
在 as 之前的 member.name 就是當選項被選擇到後的值,也就是所謂的 select。而 as 到 for 之間的則是用來當做文字內容使用的,它是個 Angular 表達式(Angular Expressions),所以筆者這就是希望是 title 加 name 再加 age 組合一起。當然這些都是從 (title, member) 中來的囉!
展開下拉選單後的樣式:
因為被指定的 select 是 member.name 而不是原本的 member 物件。所以這邊的 View 只要直接顯示 role 就可以了:
label group by group for (key, value) in object
1 2 3 | <select ng-model="role" ng-options="member.name group by member.age for (title, member) in onepiece"> <option value="">--請選擇角色--</option> </select> |
這其實是使用 group by 來指定使用 member.age 屬性來將選項分組,分組的效果其實就是 optgroup 的語法而已。
展開下拉選單後的樣式:
當選擇到某個項目時:
select as label group by group for (key, value) in object
1 2 3 | <select ng-model="role" ng-options="member as member.name group by member.age for (title, member) in onepiece"> <option value="">--請選擇角色--</option> </select> |
最後一種方式就是將前面的 select 及 group by 組合在一起而已。一般的物件並沒有像是陣列中的物件那樣有多出 track by 的語法。
展開下拉選單後的樣式:
當選擇到某個項目時:
筆者一共花了 3 篇來說明針對不同的 Model 內容來搭配 ng-options 時的各種語法,希望各位能清楚各種語法的使用時機。
好啦!最後的作業是這樣的,請以此篇的第一個範例為主,將 role 中 name 及 age 再分別綁定到兩個輸入方塊中。然後選擇不同的選項時,應該就會看到輸入方塊中有所選擇的值,這時候...請試著去改輸入方塊的值,再觀察下拉選單中的選項變化吧!