Typeahead指令是一個用於智能提示或自動完成的控件,就像Jquery的AutoComplete控件一樣。來看一個最簡單的例子:
1 <!DOCTYPE html>
2 <html ng-app="ui.bootstrap.demo" xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <link href="/Content/bootstrap.css" rel="stylesheet" />
6 <title></title>
7
8 <script src="/Scripts/angular.js"></script>
9 <script src="/Scripts/ui-bootstrap-tpls-1.3.2.js"></script>
10 <script>
11
12 angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('TypeaheadCtrl', function ($scope) { 13 $scope.selected = undefined; 14 $scope.names = [ 15 { 'name': '張三', 'ename': 'zhangsan' }, 16 { 'name': '李四', 'ename': 'lisi' }, 17 { 'name': '王五', 'ename': 'wangwu' } 18 ]; 19 }); 20 </script>
21
22 </head>
23 <body>
24 <div ng-controller="TypeaheadCtrl">
25 <input type="text" ng-model="selected" uib-typeahead="n.name as n.name+'('+n.ename+')' for n in names | filter:$viewValue | limitTo:8" class="form-control">
26 </div>
27 </body>
28 </html>
在文本框中輸入z,智能提示效果是:

選中后,文本框的值是:

uib-typeahead的用法和表單元素select中的表達式是一樣的,可以分別指定顯示的文本和選中的值。names用filter過濾器篩選輸入的數據(按數組中每個元素的每個屬性來過濾)。
uib-typeahead可以使用的屬性有:
| 屬性名 | 默認值 | 備注 |
| ng-model | 文本框的值 | |
| ng-model-options | 設置ng-model的選項。支持debounce和getterSetter | |
| typeahead-append-to | null | 指定智能提示的父元素 |
| typeahead-append-to-body | false | 智能提示內容放在 $body中,而不是它的父元素中 |
| typeahead-editable | true | 為true時文本框的值可以任意輸入,為false時文本框的值只能從智能提示列表中選取 |
| typeahead-focus-first | true | 智能提示列表中的第一個值是否獲取焦點 |
| typeahead-focus-on-select | true | 從智能提示列表中選中值后,文本框是否獲取焦點 |
| typeahead-input-formatter | undefined | 選取值后格式化文本框內容 |
| typeahead-is-open | angular.noop | 綁定一個變量,表示智能提示列表是否展開 |
| typeahead-loading | angular.noop | 綁定一個變量,表示匹配項是否異步獲取 |
| typeahead-min-length | 1 | 觸發智能提示的最小輸入字符數。必須大於等於0 |
| typeahead-no-results | angular.noop | 綁定一個變量,表示沒有找到匹配項時的處理方式 |
| typeahead-on-select($item, $model, $label, $event) | null | 從列表中選中值后的回調函數。如果選中動作不是用戶觸發的,$event則為undefined |
| typeahead-popup-template-url | uib/template/typeahead/typeahead-popup.html | |
| typeahead-select-on-blur | false | 文本框失去焦點時,選中當前高亮的匹配項 |
| typeahead-select-on-exact | false | 只有一個匹配項時自動選中 |
| typeahead-show-hint | false | 輸入內容的前半部分有匹配項時,是否提示后半部分 |
| typeahead-template-url | uib/template/typeahead/typeahead-match.html | |
| typeahead-wait-ms | 0 | 輸入字符后,等待多少毫秒觸發智能提示 |
在下面這個例子中,數據的獲取是從服務端異步獲取的:
1 <!DOCTYPE html>
2 <html ng-app="ui.bootstrap.demo" xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <link href="/Content/bootstrap.css" rel="stylesheet" />
6 <title></title>
7
8 <script src="/Scripts/angular.js"></script>
9 <script src="/Scripts/ui-bootstrap-tpls-1.3.2.js"></script>
10 <script>
11
12 angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('TypeaheadCtrl', function ($scope, $http) { 13 $scope.selected = undefined; 14
15 $scope.getNames = function (val) { 16 return $http.get('/home/GetNames', { 17 params: { 18 name: val 19 } 20 }) 21 //.success(function (data, status, config, headers) {
22 // return data;
23 //});
24 .then(function (response) { 25 return response.data; 26 }); 27 }; 28 }); 29 </script>
30
31 </head>
32 <body>
33 <div ng-controller="TypeaheadCtrl">
34 <input type="text" ng-model="selected" uib-typeahead="n.name for n in getNames($viewValue)" typeahead-loading="loadingLocations" typeahead-no-results="noResults" class="form-control">
35 <i ng-show="loadingLocations" class="glyphicon glyphicon-refresh"></i>
36 <div ng-show="noResults">
37 <i class="glyphicon glyphicon-remove"></i> No Results Found 38 </div>
39 </div>
40 </body>
41 </html>
需要注意的一點是:getNames()方法要返回一個promise,並且$http返回的promise要用.then()來處理,而不能用.success()來處理。此處有個疑問,既然.then()和.success()都是返回一個promise,為什么使用.success()時,智能提示列表無法獲取到數據?
這是一個官方的例子,用來展示如何使用typeahead-template-url:
1 <!DOCTYPE html>
2 <html ng-app="ui.bootstrap.demo" xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <link href="/Content/bootstrap.css" rel="stylesheet" />
6 <title></title>
7
8 <script src="/Scripts/angular.js"></script>
9 <script src="/Scripts/ui-bootstrap-tpls-1.3.2.js"></script>
10 <script>
11
12 angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('TypeaheadCtrl', function ($scope, $http) { 13 $scope.selected = undefined; 14
15 $scope.statesWithFlags = [{ 'name': 'Alabama', 'flag': '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png' }, { 'name': 'Alaska', 'flag': 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png' }, { 'name': 'Arizona', 'flag': '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png' }, { 'name': 'Arkansas', 'flag': '9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png' }, { 'name': 'California', 'flag': '0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png' }, { 'name': 'Colorado', 'flag': '4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png' }, { 'name': 'Connecticut', 'flag': '9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png' }, { 'name': 'Delaware', 'flag': 'c/c6/Flag_of_Delaware.svg/45px-Flag_of_Delaware.svg.png' }, { 'name': 'Florida', 'flag': 'f/f7/Flag_of_Florida.svg/45px-Flag_of_Florida.svg.png' }, { 'name': 'Georgia', 'flag': '5/54/Flag_of_Georgia_%28U.S._state%29.svg/46px-Flag_of_Georgia_%28U.S._state%29.svg.png' }, { 'name': 'Hawaii', 'flag': 'e/ef/Flag_of_Hawaii.svg/46px-Flag_of_Hawaii.svg.png' }, { 'name': 'Idaho', 'flag': 'a/a4/Flag_of_Idaho.svg/38px-Flag_of_Idaho.svg.png' }, { 'name': 'Illinois', 'flag': '0/01/Flag_of_Illinois.svg/46px-Flag_of_Illinois.svg.png' }, { 'name': 'Indiana', 'flag': 'a/ac/Flag_of_Indiana.svg/45px-Flag_of_Indiana.svg.png' }, { 'name': 'Iowa', 'flag': 'a/aa/Flag_of_Iowa.svg/44px-Flag_of_Iowa.svg.png' }, { 'name': 'Kansas', 'flag': 'd/da/Flag_of_Kansas.svg/46px-Flag_of_Kansas.svg.png' }, { 'name': 'Kentucky', 'flag': '8/8d/Flag_of_Kentucky.svg/46px-Flag_of_Kentucky.svg.png' }, { 'name': 'Louisiana', 'flag': 'e/e0/Flag_of_Louisiana.svg/46px-Flag_of_Louisiana.svg.png' }, { 'name': 'Maine', 'flag': '3/35/Flag_of_Maine.svg/45px-Flag_of_Maine.svg.png' }, { 'name': 'Maryland', 'flag': 'a/a0/Flag_of_Maryland.svg/45px-Flag_of_Maryland.svg.png' }, { 'name': 'Massachusetts', 'flag': 'f/f2/Flag_of_Massachusetts.svg/46px-Flag_of_Massachusetts.svg.png' }, { 'name': 'Michigan', 'flag': 'b/b5/Flag_of_Michigan.svg/45px-Flag_of_Michigan.svg.png' }, { 'name': 'Minnesota', 'flag': 'b/b9/Flag_of_Minnesota.svg/46px-Flag_of_Minnesota.svg.png' }, { 'name': 'Mississippi', 'flag': '4/42/Flag_of_Mississippi.svg/45px-Flag_of_Mississippi.svg.png' }, { 'name': 'Missouri', 'flag': '5/5a/Flag_of_Missouri.svg/46px-Flag_of_Missouri.svg.png' }, { 'name': 'Montana', 'flag': 'c/cb/Flag_of_Montana.svg/45px-Flag_of_Montana.svg.png' }, { 'name': 'Nebraska', 'flag': '4/4d/Flag_of_Nebraska.svg/46px-Flag_of_Nebraska.svg.png' }, { 'name': 'Nevada', 'flag': 'f/f1/Flag_of_Nevada.svg/45px-Flag_of_Nevada.svg.png' }, { 'name': 'New Hampshire', 'flag': '2/28/Flag_of_New_Hampshire.svg/45px-Flag_of_New_Hampshire.svg.png' }, { 'name': 'New Jersey', 'flag': '9/92/Flag_of_New_Jersey.svg/45px-Flag_of_New_Jersey.svg.png' }, { 'name': 'New Mexico', 'flag': 'c/c3/Flag_of_New_Mexico.svg/45px-Flag_of_New_Mexico.svg.png' }, { 'name': 'New York', 'flag': '1/1a/Flag_of_New_York.svg/46px-Flag_of_New_York.svg.png' }, { 'name': 'North Carolina', 'flag': 'b/bb/Flag_of_North_Carolina.svg/45px-Flag_of_North_Carolina.svg.png' }, { 'name': 'North Dakota', 'flag': 'e/ee/Flag_of_North_Dakota.svg/38px-Flag_of_North_Dakota.svg.png' }, { 'name': 'Ohio', 'flag': '4/4c/Flag_of_Ohio.svg/46px-Flag_of_Ohio.svg.png' }, { 'name': 'Oklahoma', 'flag': '6/6e/Flag_of_Oklahoma.svg/45px-Flag_of_Oklahoma.svg.png' }, { 'name': 'Oregon', 'flag': 'b/b9/Flag_of_Oregon.svg/46px-Flag_of_Oregon.svg.png' }, { 'name': 'Pennsylvania', 'flag': 'f/f7/Flag_of_Pennsylvania.svg/45px-Flag_of_Pennsylvania.svg.png' }, { 'name': 'Rhode Island', 'flag': 'f/f3/Flag_of_Rhode_Island.svg/32px-Flag_of_Rhode_Island.svg.png' }, { 'name': 'South Carolina', 'flag': '6/69/Flag_of_South_Carolina.svg/45px-Flag_of_South_Carolina.svg.png' }, { 'name': 'South Dakota', 'flag': '1/1a/Flag_of_South_Dakota.svg/46px-Flag_of_South_Dakota.svg.png' }, { 'name': 'Tennessee', 'flag': '9/9e/Flag_of_Tennessee.svg/46px-Flag_of_Tennessee.svg.png' }, { 'name': 'Texas', 'flag': 'f/f7/Flag_of_Texas.svg/45px-Flag_of_Texas.svg.png' }, { 'name': 'Utah', 'flag': 'f/f6/Flag_of_Utah.svg/45px-Flag_of_Utah.svg.png' }, { 'name': 'Vermont', 'flag': '4/49/Flag_of_Vermont.svg/46px-Flag_of_Vermont.svg.png' }, { 'name': 'Virginia', 'flag': '4/47/Flag_of_Virginia.svg/44px-Flag_of_Virginia.svg.png' }, { 'name': 'Washington', 'flag': '5/54/Flag_of_Washington.svg/46px-Flag_of_Washington.svg.png' }, { 'name': 'West Virginia', 'flag': '2/22/Flag_of_West_Virginia.svg/46px-Flag_of_West_Virginia.svg.png' }, { 'name': 'Wisconsin', 'flag': '2/22/Flag_of_Wisconsin.svg/45px-Flag_of_Wisconsin.svg.png' }, { 'name': 'Wyoming', 'flag': 'b/bc/Flag_of_Wyoming.svg/43px-Flag_of_Wyoming.svg.png' }]; 16 }); 17 </script>
18
19 </head>
20 <body>
21 <script type="text/ng-template" id="customTemplate.html">
22 <a>
23 <img ng-src="http://upload.wikimedia.org/wikipedia/commons/thumb/{{match.model.flag}}" width="16">
24 <span ng-bind-html="match.label | uibTypeaheadHighlight:query"></span>
25 </a>
26 </script>
27 <div ng-controller="TypeaheadCtrl">
28 <input type="text" ng-model="selected" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-template-url="customTemplate.html" class="form-control" >
29 </div>
30 </body>
31 </html>
模板中的match表示智能提示列表中每一個匹配的選項,包含3個屬性:id,label,model。label是綁定到列表中的每一項的文本,即state as state.name for state in statesWithFlags | filter:{name:$viewValue}中的state.name。model是列表中的每一項,即statesWithFlags數組中的每個元素。
效果是這樣:

目錄:
AngularJs的UI組件ui-Bootstrap分享(一)
AngularJs的UI組件ui-Bootstrap分享(二)——Collapse
AngularJs的UI組件ui-Bootstrap分享(三)——Accordion
AngularJs的UI組件ui-Bootstrap分享(四)——Datepicker Popup
AngularJs的UI組件ui-Bootstrap分享(五)——Pager和Pagination
AngularJs的UI組件ui-Bootstrap分享(六)——Tabs
AngularJs的UI組件ui-Bootstrap分享(七)——Buttons和Dropdown
AngularJs的UI組件ui-Bootstrap分享(八)——Tooltip和Popover
AngularJs的UI組件ui-Bootstrap分享(九)——Alert
AngularJs的UI組件ui-Bootstrap分享(十)——Model
AngularJs的UI組件ui-Bootstrap分享(十一)——Typeahead
AngularJs的UI組件ui-Bootstrap分享(十二)——Rating
AngularJs的UI組件ui-Bootstrap分享(十三)——Progressbar
AngularJs的UI組件ui-Bootstrap分享(十四)——Carousel

