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


          在前几篇随笔简单介绍了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

    1.        Remote(Boolean)是否为远程调用,truesourceurlfalse则为scope上的一个属性或者函数。
    2.        Source:数据源,urlscope属性或者函数。
    3.        min-length:开始显示下拉条的最小长度。
    4.        position-myposition-atjQuery下拉条显示样式
    5.       start-with:(Boolean)是否为以前缀开始的帅选,默认false(包含)。
    6.    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

  • 相关阅读:
    关于二分操作的基本应用
    东北育才 d1t4 漂流
    东北育才 d1t1 优雅的序列
    从零开始的图的存储方法
    从零理解的KMP算法
    openjudge T017 黑社会团伙 (并查集)
    东北育才 day6
    poj3071 Football
    noip2015 跳石头
    noip2015 信息传递
  • 原文地址:https://www.cnblogs.com/whitewolf/p/2667365.html
Copyright © 2020-2023  润新知