您的位置:首页 > Web前端 > AngularJS

基于jQuery UI Autocomplete的AngularJS 指令(directive)扩展 推荐

2012-09-02 10:45 826 查看
在前几篇随笔简单介绍了AngularJS,在AngularJS 指令(directive)是重要的概念,主要负责了很大部分的组建样式交互。在前面介绍过directive需要预先的模板编译在返回一个link的函数,注册行为事件交互等等。在这里不多说了,关于指令的介绍将在后续一并补上。在这里我们先看一个利用jQuery UI组件开发的AngularJS Autocomplete指令。

代码:jsfiddle在线测试

Directive:

1 var oldSuggest = jQuery.ui.autocomplete.prototype._suggest;

2 jQuery.ui.autocomplete.prototype._suggest = function(items) {

3 var itemsArray = items;

4 if (this.options.maxItems && this.options.maxItems > 0) {

5 itemsArray = items.slice(0, this.options.maxItems);

6 }

7 oldSuggest.call(this, itemsArray);

8 };

9

10 var autocomplete = function() {

11 var linkFun = function($scope, element, attrs) {

12 var $input = jQuery(element);

13 var responseDataSource = function($scope, source, pattern, response) {

14 var express = $scope[source];

15 var data = typeof(express) === "function" ? express(pattern, response) : express;

16 if (data) {

17 response(data);

18 }

19 };

20 var option = attrs;

21 //

22 option.position = {

23 my: attrs.positionMy,

24 at: attrs.positionAt,

25 };

26 var option = jQuery.extend({

27 position: {

28 my: "",

29 at: ""

30 },

31 close: function(event, ui) {

32 var express = attrs["ngModel"] + "='" + $input.val() + "'";

33 $scope.$apply(express);

34 $scope.$eval(attrs["ngChange"]);

35 }

36 }, option);

37 option.remote = option.remote === "true";

38 if (!option.remote) {

39 option.dataSource = attrs.source;

40 option.source = function(pattern, response) {

41 var option = $input.autocomplete("option");

42 var responseEx = function(data) {

43 var matches = jQuery.map(data, function(tag) {

44 var startWith = attrs.startWith === "true";

45 var index = tag.toUpperCase().indexOf(pattern.term.toUpperCase())

46 if ((startWith && index === 0) || (!startWith && index > -1)) {

47 return tag;

48 }

49 })

50 response(matches);

51 };

52 responseDataSource($scope, option.dataSource, pattern, responseEx);

53 };

54 } else {

55 option.source = option.source; //remote url

56 }

57 $input.autocomplete(option);

58 };

59 return linkFun;

60 };

61

62 var prefixed = "green";

63 var appMoule = angular.module('app', []);

64
65 appMoule.directive(prefixed + "Autocomplete", autocomplete);

在指令中主需要标注html attribute green-autocomplete=””引用.

以及一些特殊option:

Remote:(Boolean)是否为远程调用,true则source为url,false则为scope上的一个属性或者函数。

Source:数据源,url、scope属性或者函数。

min-length:开始显示下拉条的最小长度。

position-my,position-at:jQuery下拉条显示样式

start-with:(Boolean)是否为以前缀开始的帅选,默认false(包含)。

max-items:显示最大下拉项数目。

测试代码:

html: 1 <div ng-app="app" ng-controller="Test">

2 <div class="ui-widget">

3 <label for="tags">Tags(变量): </label>

4 <input id="tags" ng-model="val" green-autocomplete="" remote="false" ng-disabled="val=='Asp'" source="getsource" min-length="0" position-my="right top" position-at= "right bottom" start-with="false">

5 </div>

6 <br/>

7 `val`

8

9 <div class="ui-widget">

10 <label for="tags">Tags(函数): </label>

11 <input i ng-model="val_Array" green-autocomplete="" source="availableTags" max-items="5" min-length="2" start-with="true" ng-change="change();">

12 </div>

13 <br/>`val_Array`

14 http://XX/XX.php?term={0}
15 <div class="ui-widget">

16 <label for="tags">Tags(url): </label>

17 <input i ng-model="val_url" green-autocomplete="" source="url" remote="true" max-items="3" >

18 </div>

19 <br/>

20 `val_url`

21 </div>

javascript:

1 //test controller

2 var test = function($scope) {

3 $scope.availableTags = [

4 "ActionScript",

5 "AppleScript",

6 "Asp",

7 "BASIC",

8 "C",

9 "C++",

10 "Clojure",

11 "COBOL",

12 "ColdFusion",

13 "Erlang",

14 "Fortran",

15 "Groovy",

16 "Haskell",

17 "Java",

18 "JavaScript",

19 "Lisp",

20 "Perl",

21 "PHP",

22 "Python",

23 "Ruby",

24 "Scala",

25 "Scheme"

26 ];

27

28 $scope.getsource = function(pattern, response) {

29 response($scope.availableTags);

30 };

31 $scope.change = function() {

32 console.log('change', $scope.val_Array);

33 };

34 };

35

36 appMoule.controller("Test", test);

37 //mock ajax.

38 var oldAjax = jQuery.ajax;

39 jQuery.ajax = function(param) {

40 if (param.url === "url") {

41 var term = param.data.term;

42 param.success([term + "1", term + "2", 3 + term, 4 + term]);

43 }

44 else {

45 oldAjax(param);

46 }

47 };

48
49 //jQuery.ajax({url:"text.html"}); must erroe:GET http://fiddle.jshell.net/_display/text.html 404 (NOT FOUND)

在测试中为了验证url,本想通过自己的博客导入json数据,但是跨域等问题,所以没办法,在最后选择了mock jQuery.Ajax,本想引入jasmine测试框架利用spyOn(jasmine测试mock文档:

http://pivotal.github.com/jasmine/jsdoc/symbols/jasmine.Spy.html),但是找了很久没找到在线引用包。最后采用手动血mock代码如下:

1 //mock ajax.
2  var oldAjax = jQuery.ajax;
3  jQuery.ajax = function(param) {
4      if (param.url === "url") {
5          var term = param.data.term;
6          param.success([term + "1", term + "2", 3 + term, 4 + term]);
7      }
8      else {
9          oldAjax(param);
10      }
11  };

所以你看见的第三个返回值永远会是输入前缀加1,2,3.

测试第一输入框测试scope属性,第二测试scope函数(有两个输入参数),第三测试url ajax。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息