麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

AngularJS封裝指令方法詳解

2019-11-19 18:33:46
字體:
來源:轉載
供稿:網友

本文實例講述了AngularJS封裝指令方法。分享給大家供大家參考,具體如下:

引言:angularjs是一個中等重量級的前端開發框架

HTML是一門很好的為靜態文本設計的語言,但要構建動態的web應用它就顯的乏力了。通常,我們使用以下技術來解決靜態網頁技術在構建動態應用上的不足:

1.類庫:類庫是一類函數的集合,它能幫助你寫web應用。這里起主導作用是你的代碼,由你來決定何時使用類庫。典型的類庫,例如prototype、jQuery等。

2.框架:框架式一種特殊的、已經實現的web應用,你只需要填充具體的業務邏輯。這里框架是起主導作用的,由它根據具體的邏輯來調用你的代碼。典型的框架例如knockout,sproutcore, YUI等。AngularJS也是其中之一。

框架又有輕重之分。我對輕重的判斷標準是,是否需要很多的第三方類庫來幫助你實現功能。顯然,backbone這種屬于輕量級框架,它簡單易用,專注于前端Mvc的實現,故而你還需要很多第三方類庫(至少jquery)來完成dom操作、UI等各種各樣的內容。Yui、dojo屬于重型框架,他們的作者企圖搞出一個森羅萬象的框架+組件庫,包括代碼動態調用、各種UI組件都包含在內,學習成本較高,但是一旦精通,至少這個項目別無所求。從這個角度講,輕量級框架好比毛坯房,還需要各種工具做裝修,但是對于開發者來說也更靈活。重量級框架好比精裝修的房間,你只需要的是適應它,但如果要自己做出大刀闊斧的修改,那就稍微有點傷經動骨了。

angularjs,在我看來是介于以上兩類之間,是個中等重量級的框架。即不像backbone那么簡單,也不像dojo和Yui那么包羅萬象。很多時候,妄圖包羅萬象,往往會出現很多子模塊的質量高不成低不就,并且修改起來較為困難。過分精簡,則框架內容單薄需要寫的內容太多。angularjs這種相對中庸的風格,則非常符合我的需求。目前,AngularJS三個我認為最為精妙的組件就是數據綁定(Scope),指令(Directive)和依賴注入(Dependency Injection),表現得非常好。相對而言,它的UI組件和動畫則是弱項。可以說,選擇了angularjs,就意味著選擇了jquery式的組件庫方式來彌補它的不足,要完成一個web應用必須跟第三方類庫打交道。

現在已經有許多針對angularjs寫的UI插件,有的是結合了bootstrap,有的是結合了jquery, 雖然不太完善,都很值得參考:http://angular-ui.github.io/

與jquery類庫的協作

第三方類庫中,不得不提的是大名鼎鼎的jquery,現在基本上已經是國內web開發的必修工具了。它靈活的dom操作,讓很多web開發人員欲罷不能。再加上已經很成熟的jquery UI 庫和大量jquery 插件,幾乎是一個取之不盡用之不竭的寶庫。然而,它是否能與angularjs結合呢?

很多angularjs原教旨主義者對此持否定態度。他們認為,既然已經使用了angularjs做web應用框架,那就必須避免其他類庫的干擾,做純凈的MvvM模式應用。任何類似jquery的dom操作,都是不潔的。把所有和界面相關的, 比如dom操作, 都放在directive中, 這樣頁面中directive而沒有代碼,跟JSF思想一致。MVVM,DSL,組件化的思想這才是web的趨勢。嗯,想法很好,原教旨主義者想法都是這么純潔。但事實情況是,使用了angularjs我們就離不開jquery。

眾所周知,angularjs里面事實上已經內置了jquery lite.,而且angularjs源碼中很多方法直接就是使用jquery方法。例如angularjs的事件綁定機制。既然先知們都在用,我們又何苦不用?組件化的思想沒有錯,但沒必要因此把自己的手腳綁住。唯一要注意的問題是,不要用jquery的代碼破壞了angularjs的結構。對此我的原則如下,不足之處還請指出:

模塊劃分、服務、路由、依賴注入等重要方面上都得使用angularjs的方式,只有某些具體內容(通常是一些Ui)才使用jquery。 避免在controller里面寫了一堆直接操作dom元素的 jquery代碼。使用angularjs的模板綁定機制。 常用的組件要用angularjs的方法抽取出來,但組件具體實現則不必糾結于是否使用jquery及其插件。 .使用第三方類庫時,在變量和函數命名時有特殊標記(通常是加上這個類庫名的縮寫)。

jquery,更是建議作為angularjs的依賴,先于angularjs加載進來。

事實上,選擇了angularjs這樣的框架中德中等重量級選手,就意味著你必須添加其他類庫。而jquery,更是建議作為angularjs的依賴,先于angularjs加載進來。因為在查看angularjs API的時候,我已經發現,其中許多功能,事實上是依賴于jquery的。典型的例子,就是官網的ng-blur指令。

<input type="text" ng-model="name" ng-blur="checkname()" > ng-blur指令,是在焦點離開某個元素時觸發的指令。對于上例,即在焦點離開該文本輸入框時,觸發checkname()函數。

看起來很簡單,但是你如果真的使用了這個指令,你就會發現它根本不起效果。在仔細查看文檔后,我才發現這實際是先知們使用jquery的blur方法實現的函數(而且事實上根本沒有真正實現并放在當前的版本里)。那么就算我們想寫一個,離開jquery原生庫是不行的,因為blur方法并未封裝到angularjs內帶的jquery lite里。換句話說,必須先載入完整的jquery才能使用。于是,我干脆自己寫了一個標簽:

/** angular directive onBlur** @description my ng-blur* @require jquery*/$compileProvider.directive('onBlur', function() {  return {    restrict : 'A',    link : function(scope, elm, attrs) {      elm.bind('blur', function() {        scope.$apply(attrs.onBlur);      });    }  };});

這已經很好了。

但是還不夠完美。由于$apply方法接受函數的問題,所以直接像上面這樣寫,有可能導致angularjs運行時報錯:$apply already in progress

避免這個問題的發生,則需要對$apply方法進行加工:

/* factory function safeApply** @description If you find yourself triggering the '$apply already in progress' error while developing with Angular.JS* (for me I find I hit most often when integrating third party plugins that trigger a lot of DOM events),* you can use a 'safeApply' method that checks the current phase before executing your function.** @param scope, the action scope, mostly is the topmost controller* @param fn, the function which you want to apply into scope* @see https://coderwall.com/p/ngisma*/.factory('safeApply', function($rootScope) {  return function(scope, fn) {    var phase = scope.$root.$$phase;    if (phase == '$apply' || phase == '$digest') {      if (fn && ( typeof (fn) === 'function')) {        fn();      }    } else {      scope.$apply(fn);    }  }});

那么之前的onblur標簽,就應該改為:

/** angular directive onBlur** @description my ng-blur* @require jquery*/$compileProvider.directive('onBlur', function(safeApply) {  return {    restrict : 'A',    link : function(scope, elm, attrs) {      elm.bind('blur', function() {        safeApply(scope, attrs.onBlur);      });    }  };});

以上代碼我已經加入了自己的angular_extend模塊,在自己的項目中使用了,效果很好。

將jquery 插件用angularjs的方式封裝成組件的例子

icheck是一個jquery插件,用于跨瀏覽器美化Checkbox和Radio按紐。關于它的介紹,在http://www.bootcss.com/p/icheck/

一般來說,它的使用方法是在dom載入后加一段jquery代碼:

$('input').iCheck({  labelHover : false,  cursor : true,  checkboxClass : 'icheckbox_square-blue',  radioClass : 'iradio_square-blue',  increaseArea : '20%'});

但是既然要放在我們的項目里,就不能到處塞這種直接操作dom的jquery代碼,既不美觀,也不易維護。按照之前所說的原則,最好將其封裝成angular指令的模式,放在公共模塊里來調用。這里我將我新建的指令命名為ng-icheck。如此,我們只要寫在某個checkbox或者radio的html標簽里加上一句ng-ickeck即可。具體實現如下:

/* * angular directive ng-icheck * * @description icheck is a plugin of jquery for beautifying checkbox & radio, now I complied it with angular directive * @require jquery, icheck * @example <input type="radio" ng-model="paomian" value="kangshifu" ng-icheck> *     <input type="checkbox" class="icheckbox" name="mantou" ng-model="mantou" ng-icheck checked> */$compileProvider.directive('ngIcheck', function($compile) {  return {    restrict : 'A',    require : '?ngModel',    link : function($scope, $element, $attrs, $ngModel) {      if (!$ngModel) {        return;      }      //using iCheck      $($element).iCheck({        labelHover : false,        cursor : true,        checkboxClass : 'icheckbox_square-blue',        radioClass : 'iradio_square-blue',        increaseArea : '20%'      }).on('ifClicked', function(event) {        if ($attrs.type == "checkbox") {          //checkbox, $ViewValue = true/false/undefined          $scope.$apply(function() {            $ngModel.$setViewValue(!($ngModel.$modelValue == undefined ? false : $ngModel.$modelValue));          });        } else {          // radio, $ViewValue = $attrs.value          $scope.$apply(function() {            $ngModel.$setViewValue($attrs.value);          });        }      });    },  };});

在以上代碼中值得注意的是:使用了icheck插件后,會生成一個美化過的div覆蓋在原來的checkbox或者radio之上,而原來的checkbox或者radio會被影藏。故而,當我們點擊它們時,不會直接觸發事件,使得綁定到checkbox或者radio上的model值改變。所以我們這里需要重新綁定事件,使用

$ngModel.$setViewValue() 方法來給model賦值。具體邏輯,則相根據checkbox和radio而不同。詳見以上代碼。

由于以上代碼寫在我的項目中的通用模塊common_angular_component.js里,故而在調用了該通用模塊的頁面里,直接使用ng-icheck指令即可實現ickeck的美化效果,同時避免了大量重復的jquery代碼的出現。

更多關于AngularJS相關內容感興趣的讀者可查看本站專題:《AngularJS入門與進階教程》及《AngularJS MVC架構總結

希望本文所述對大家AngularJS程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: bt 自拍 另类 综合 欧美 | 国产品久久 | 色综合久久久久综合99 | 91av资源在线 | 狠狠干b | 欧美成人午夜影院 | 男女羞羞视频在线观看免费 | 欧美一级免费视频 | 国产美女做爰免费视 | 国产成人综合在线视频 | 久久久久久久免费精品 | av中文字幕免费在线观看 | 91美女福利视频 | 毛片视频播放 | 国产污污视频 | 久久伊人精品视频 | 日本羞羞的午夜电视剧 | 国产一区二区三区在线视频 | 国产三级精品最新在线 | 在线a毛片免费视频观看 | 国产精品一区网站 | 91成| 国产乱弄 | xnxx 美女19 | 国人精品视频在线观看 | 日本精品久久久久 | 成人小视频免费在线观看 | 久久视讯| 精品一区二区久久久久久按摩 | 黄色a级片免费观看 | 黄色免费入口 | a集毛片| 羞羞的视频免费在线观看 | sm高h视频 | 一级黄色影院 | 成人男女激情免费视频 | 2级毛片| 欧美视频99 | 国产精品自拍99 | 一区在线看 | 亚洲99|