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

代码:jsfiddle在线测试

Directive:

1varoldSuggest=jQuery.ui.autocomplete.prototype._suggest;
2jQuery.ui.autocomplete.prototype._suggest=function(items){
3varitemsArray=items;
4if(this.options.maxItems&&this.options.maxItems>0){
5itemsArray=items.slice(0,this.options.maxItems);
6}
7oldSuggest.call(this,itemsArray);
8};
9
10varautocomplete=function(){
11varlinkFun=function($scope,element,attrs){
12var$input=jQuery(element);
13varresponseDataSource=function($scope,source,pattern,response){
14varexpress=$scope[source];
15vardata=typeof(express)==="function"?express(pattern,response):express;
16if(data){
17response(data);
18}
19};
20varoption=attrs;
21//
22option.position={
23my:attrs.positionMy,
24at:attrs.positionAt,
25};
26varoption=jQuery.extend({
27position:{
28my:"",
29at:""
30},
31close:function(event,ui){
32varexpress=attrs["ngModel"]+"='"+$input.val()+"'";
33$scope.$apply(express);
34$scope.$eval(attrs["ngChange"]);
35}
36},option);
37option.remote=option.remote==="true";
38if(!option.remote){
39option.dataSource=attrs.source;
40option.source=function(pattern,response){
41varoption=$input.autocomplete("option");
42varresponseEx=function(data){
43varmatches=jQuery.map(data,function(tag){
44varstartWith=attrs.startWith==="true";
45varindex=tag.toUpperCase().indexOf(pattern.term.toUpperCase())
46if((startWith&&index===0)||(!startWith&&index>-1)){
47returntag;
48}
49})
50response(matches);
51};
52responseDataSource($scope,option.dataSource,pattern,responseEx);
53};
54}else{
55option.source=option.source;//remoteurl
56}
57$input.autocomplete(option);
58};
59returnlinkFun;
60};
61
62varprefixed="green";
63varappMoule=angular.module('app',[]);
64

65appMoule.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<divng-app="app"ng-controller="Test">

2<divclass="ui-widget">
3<labelfor="tags">Tags(变量):</label>
4<inputid="tags"ng-model="val"green-autocomplete=""remote="false"ng-disabled="val=='Asp'"source="getsource"min-length="0"position-my="righttop"position-at="rightbottom"start-with="false">
5</div>
6<br/>
7`val`
8
9<divclass="ui-widget">
10<labelfor="tags">Tags(函数):</label>
11<inputing-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`
14http://XX/XX.php?term={0}
15<divclass="ui-widget">
16<labelfor="tags">Tags(url):</label>
17<inputing-model="val_url"green-autocomplete=""source="url"remote="true"max-items="3">
18</div>
19<br/>
20`val_url`
21</div>

javascript:

1//testcontroller
2vartest=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){
29response($scope.availableTags);
30};
31$scope.change=function(){
32console.log('change',$scope.val_Array);
33};
34};
35
36appMoule.controller("Test",test);
37//mockajax.
38varoldAjax=jQuery.ajax;
39jQuery.ajax=function(param){
40if(param.url==="url"){
41varterm=param.data.term;
42param.success([term+"1",term+"2",3+term,4+term]);
43}
44else{
45oldAjax(param);
46}
47};
48

49//jQuery.ajax({url:"text.html"});musterroe:GEThttp://fiddle.jshell.net/_display/text.html404(NOTFOUND)

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

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

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

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

测试第一输入框测试scope属性,第二测试scope函数(有两个输入参数),第三测试url ajax。