日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
AngularJS指令(Directives)實(shí)踐指南

指令(Directives)是所有AngularJS應(yīng)用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要創(chuàng)建應(yīng)用特定的指令。這篇教程會為你講述如何自定義指令,以及介紹如何在實(shí)際項(xiàng)目中使用。在這篇文章的***(第二部分),我會指導(dǎo)你如何使用Angular指令來創(chuàng)建一個簡單的記事本應(yīng)用。

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比婁底網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式婁底網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋婁底地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。

概述

一個指令用來引入新的HTML語法。指令是DOM元素上的標(biāo)記,使元素?fù)碛刑囟ǖ男袨?。舉例來說,靜態(tài)的HTML不知道如何來創(chuàng)建和展現(xiàn)一個日期選擇器控件。讓HTML能識別這個語法,我們需要使用指令。指令通過某種方法來創(chuàng)建一個能夠支持日期選擇的元素。我們會循序漸進(jìn)地介紹這是如何實(shí)現(xiàn)的。 如果你寫過AngularJS的應(yīng)用,那么你一定已經(jīng)使用過指令,不管你有沒有意識到。你肯定已經(jīng)用過簡單的指令,比如 ng-mode, ng-repeat, ng-show等。這些指令都賦予DOM元素特定的行為。例如,ng-repeat 重復(fù)特定的元素,ng-show 有條件地顯示一個元素。如果你想讓一個元素支持拖拽,你也需要創(chuàng)建一個指令來實(shí)現(xiàn)它。指令背后基本的想法很簡單。它通過對元素綁定事件監(jiān)聽或者改變DOM而使HTML擁有真實(shí)的交互性。

jQuery視角

想象一下使用jQuery如何創(chuàng)建一個日期選擇器。首先,我們在HTML中添加一個普通的輸入框,然后通過jQuery調(diào)用 $(element).dataPicker() 來將它轉(zhuǎn)變成一個日期選擇器。但是,仔細(xì)想一下。當(dāng)一個設(shè)計(jì)人員過來檢查HTML標(biāo)記的時候,他/她能否立刻猜到這個字段實(shí)際上表示的內(nèi)容?這只是一個簡單的輸入框,或者一個日期選擇器?你需要查看jQuery代碼來確定這些。而Angular的方法是使用一個指令來擴(kuò)展HTML。所以,一個日期選擇器的指令可以是下面的形式:

 
 
  1.  

或者是這樣:

 
 
  1.  

這種創(chuàng)建UI組建的方式更加直接和清晰。你可以輕易地通過查看元素就明白這到底是什么。

創(chuàng)建自定義指令:

一個Angular指令可以有以下的四種表現(xiàn)形式: 1. 一個新的HTML元素() 2. 元素的屬性() 3. CSS class() 4. 注釋() 當(dāng)然,我們可以控制我們的指令在HTML中的表現(xiàn)形式。下面我們來看一下AngularJS中的一個典型的指令的寫法。指令注冊的方式與 controller 一樣,但是它返回的是一個擁有指令配置屬性的簡單對象(指令定義對象) 。下面的代碼是一個簡單的 Hello World 指令。

 
 
  1. var app = angular.module('myapp', []);  
  2.    
  3. app.directive('helloWorld', function() {  
  4.   return {  
  5.       restrict: 'AE',  
  6.       replace: 'true',  
  7.       template: '

    Hello World!!

  8.   };  
  9. });  

在上面的代碼中,app.directive()方法在模塊中注冊了一個新的指令。這個方法的***個參數(shù)是這個指令的名字。第二個參數(shù)是一個返回指令定義對象的函數(shù)。如果你的指令依賴于其他的對象或者服務(wù),比如 $rootScope, $http, 或者$compile,他們可以在這個時間被注入。這個指令在HTML中以一個元素使用,如下:

 
 
  1.  
  2. //OR  
  3.  

或者,以一個屬性的方式使用:

 
 
 
  • //OR  
  •  
  • 如果你想要符合HTML5的規(guī)范,你可以在元素前面添加 x- 或者 data-的前綴。所以下面的標(biāo)記也會匹配 helloWorld 指令:

     
     
     
  • //OR  
  •  

    注意: 在匹配指令的時候,Angular會在元素或者屬性的名字中剔除 x- 或者 data- 前綴。 然后將 – 或者 : 連接的字符串轉(zhuǎn)換成駝峰(camelCase)表現(xiàn)形式,然后再與注冊過的指令進(jìn)行匹配。這是為什么,我們在HTML中以 hello-world 的方式使用 helloWorld 指令。其實(shí),這跟HTML對標(biāo)簽和屬性不區(qū)分大小寫有關(guān)。 盡管上面的指令僅僅實(shí)現(xiàn)了靜態(tài)文字的顯示,但是這里還是有一些有趣的點(diǎn)值得我們?nèi)ネ诰?。我們在指令定義過程中使用了三個屬性來配置指令。我們來一一介紹他們的作用。

    • restrict – 這個屬性用來指定指令在HTML中如何使用(還記得之前說的,指令的四種表示方式嗎)。在上面的例子中,我們使用了 ‘AE’。所以這個指令可以被當(dāng)作新的HTML元素或者屬性來使用。如果要允許指令被當(dāng)作class來使用,我們將 restrict 設(shè)置成 ‘AEC’。
    • template – 這個屬性規(guī)定了指令被Angular編譯和鏈接(link)后生成的HTML標(biāo)記。這個屬性值不一定要是簡單的字符串。template 可以非常復(fù)雜,而且經(jīng)常包含其他的指令,以及表達(dá)式({{ }})等。更多的情況下你可能會見到 templateUrl, 而不是 template。所以,理想情況下,你應(yīng)該將模板放到一個特定的HTML文件中,然后將 templateUrl 屬性指向它。
    • replace – 這個屬性指明生成的HTML內(nèi)容是否會替換掉定義此指令的HTML元素。在我們的例子中,我們用 的方式使用我們的指令,并且將 replace 設(shè)置成 true。所以,在指令被編譯之后,生成的模板內(nèi)容替換掉了 。最終的輸出是

      Hello World!!

      。如果你將 replace 設(shè)置成 false,也就是默認(rèn)值,那么生成的模板會被插入到定義指令的元素中。

    打開這個 plunker,在”Hello World!!”右鍵檢查元素內(nèi)容,來更形象地明白這些。

    Link函數(shù)和Scope

    指令生成出的模板其實(shí)沒有太多意義,除非它在特定的scope下編譯。默認(rèn)情況下,指令并不會創(chuàng)建新的子scope。更多的,它使用父scope。也就是說,如果指令存在于一個controller下,它就會使用這個controller的scope。 如何運(yùn)用scope,我們要用到一個叫做 link 的函數(shù)。它由指令定義對象中的link屬性配置。讓我們來改變一下我們的 helloWorld 指令,當(dāng)用戶在一個輸入框中輸入一種顏色的名稱時,Hello World 文字的背景色自動發(fā)生變化。同時,當(dāng)用戶在 Hello World 文字上點(diǎn)擊時,背景色變回白色。 相應(yīng)的HTML標(biāo)記如下:

     
     
    1.  
    2.     
    3.     
    4.  

    修改后的 helloWorld 指令如下:

     
     
    1. app.directive('helloWorld', function() {  
    2.   return {  
    3.     restrict: 'AE',  
    4.     replace: true,  
    5.     template: 'Hello World',  
    6.     link: function(scope, elem, attrs) {  
    7.       elem.bind('click', function() {  
    8.         elem.css('background-color', 'white');  
    9.         scope.$apply(function() {  
    10.           scope.color = "white";  
    11.         });  
    12.       });  
    13.       elem.bind('mouseover', function() {  
    14.         elem.css('cursor', 'pointer');  
    15.       });  
    16.     }  
    17.   };  
    18. });  

    我們注意到指令定義中的 link 函數(shù)。 它有三個參數(shù):

    • scope – 指令的scope。在我們的例子中,指令的scope就是父controller的scope。
    • elem – 指令的jQLite(jQuery的子集)包裝DOM元素。如果你在引入AngularJS之前引入了jQuery,那么這個元素就是jQuery元素,而不是jQLite元素。由于這個元素已經(jīng)被jQuery/jQLite包裝了,所以我們就在進(jìn)行DOM操作的時候就不需要再使用 $()來進(jìn)行包裝。
    • attr – 一個包含了指令所在元素的屬性的標(biāo)準(zhǔn)化的參數(shù)對象。舉個例子,你給一個HTML元素添加了一些屬性:,那么可以在 link 函數(shù)中通過 attrs.someAttribute 來使用它。

    link函數(shù)主要用來為DOM元素添加事件監(jiān)聽、監(jiān)視模型屬性變化、以及更新DOM。在上面的指令代碼片段中,我們添加了兩個事件, click,和 mouseover。click 處理函數(shù)用來重置

    的背景色,而 mouseover 處理函數(shù)改變鼠標(biāo)為 pointer。在模板中有一個表達(dá)式 {{color}},當(dāng)父scope中的 color 發(fā)生變化時,它用來改變 Hello World 文字的背景色。 這個 plunker 演示了這些概念。

    #p#

    compile函數(shù)

    compile 函數(shù)在 link 函數(shù)被執(zhí)行之前用來做一些DOM改造。它接收下面的參數(shù):

    • tElement – 指令所在的元素
    • attrs – 元素上賦予的參數(shù)的標(biāo)準(zhǔn)化列表

    要注意的是 compile 函數(shù)不能訪問 scope,并且必須返回一個 link 函數(shù)。但是如果沒有設(shè)置 compile 函數(shù),你可以正常地配置 link 函數(shù),(有了compile,就不能用link,link函數(shù)由compile返回)。compile函數(shù)可以寫成如下的形式:

     
     
    1. app.directive('test', function() {  
    2.   return {  
    3.     compile: function(tElem,attrs) {  
    4.       //do optional DOM transformation here  
    5.       return function(scope,elem,attrs) {  
    6.         //linking function here  
    7.       };  
    8.     }  
    9.   };  
    10. });  

    大多數(shù)的情況下,你只需要使用 link 函數(shù)。這是因?yàn)榇蟛糠值闹噶钪恍枰紤]注冊事件監(jiān)聽、監(jiān)視模型、以及更新DOM等,這些都可以在 link 函數(shù)中完成。 但是對于像 ng-repeat 之類的指令,需要克隆和重復(fù) DOM 元素多次,在 link 函數(shù)執(zhí)行之前由 compile 函數(shù)來完成。這就帶來了一個問題,為什么我們需要兩個分開的函數(shù)來完成生成過程,為什么不能只使用一個?要回答好這個問題,我們需要理解指令在Angular中是如何被編譯的!

    指令是如何被編譯的

    當(dāng)應(yīng)用引導(dǎo)啟動的時候,Angular開始使用 $compile 服務(wù)遍歷DOM元素。這個服務(wù)基于注冊過的指令在標(biāo)記文本中搜索指令。一旦所有的指令都被識別后,Angular執(zhí)行他們的 compile 方法。如前面所講的,compile 方法返回一個 link 函數(shù),被添加到稍后執(zhí)行的 link 函數(shù)列表中。這被稱為編譯階段。如果一個指令需要被克隆很多次(比如 ng-repeat),compile函數(shù)只在編譯階段被執(zhí)行一次,復(fù)制這些模板,但是link 函數(shù)會針對每個被復(fù)制的實(shí)例被執(zhí)行。所以分開處理,讓我們在性能上有一定的提高。這也說明了為什么在 compile 函數(shù)中不能訪問到scope對象。 在編譯階段之后,就開始了鏈接(linking)階段。在這個階段,所有收集的 link 函數(shù)將被一一執(zhí)行。指令創(chuàng)造出來的模板會在正確的scope下被解析和處理,然后返回具有事件響應(yīng)的真實(shí)的DOM節(jié)點(diǎn)。

    改變指令的Scope

    默認(rèn)情況下,指令獲取它父節(jié)點(diǎn)的controller的scope。但這并不適用于所有情況。如果將父controller的scope暴露給指令,那么他們可以隨意地修改 scope 的屬性。在某些情況下,你的指令希望能夠添加一些僅限內(nèi)部使用的屬性和方法。如果我們在父的scope中添加,會污染父scope。 其實(shí)我們還有兩種選擇:

    • 一個子scope – 這個scope原型繼承子父scope。
    • 一個隔離的scope – 一個孤立存在不繼承自父scope的scope。

    這樣的scope可以通過指令定義對象中 scope 屬性來配置。下面的代碼片段是一個例子:

     
     
    1. app.directive('helloWorld', function() {  
    2.   return {  
    3.     scope: true,  // use a child scope that inherits from parent  
    4.     restrict: 'AE',  
    5.     replace: 'true',  
    6.     template: '

      Hello World!!

    7.   };  
    8. });  

    上面的代碼,讓Angular給指令創(chuàng)建一個繼承自父socpe的新的子scope。 另外一個選擇,隔離的scope:

     
     
    1. app.directive('helloWorld', function() {  
    2.   return {  
    3.     scope: {},  // use a new isolated scope  
    4.     restrict: 'AE',  
    5.     replace: 'true',  
    6.     template: '

      Hello World!!

    7.   };  
    8. });  

    這個指令使用了一個隔離的scope。隔離的scope在我們想要創(chuàng)建可重用的指令的時候是非常有好處的。通過使用隔離的scope,我們能夠保證我們的指令是自包含的,可以被很容易的插入到HTML應(yīng)用中。 它內(nèi)部不能訪問父的scope,所保證了父scope不被污染。 在我們的 helloWorld 指令例子中,如果我們將 scope 設(shè)置成 {},那么上面的代碼將不會工作。 它會創(chuàng)建一個新的隔離的scope,那么相應(yīng)的表達(dá)式 {{color}} 會指向到這個新的scope中,它的值將是 undefined. 使用隔離的scope并不意味著我們完全不能訪問父scope的屬性。其實(shí)有一些技術(shù)可以允許我們訪問父scope的屬性,甚至監(jiān)視他們的變化。我們會在指令這個系列的第二部分中討論這些技術(shù),以及一些更高級的概念,比如 Controller 函數(shù)。 第二部分也會和你一起使用Angular指令創(chuàng)建一個較為豐富的記事本應(yīng)用。 所以,請保持關(guān)注。

    原文鏈接: sitepoint   翻譯: 伯樂在線 - 陳 鑫偉

    譯文鏈接: http://blog.jobbole.com/62249/


    網(wǎng)頁標(biāo)題:AngularJS指令(Directives)實(shí)踐指南
    地址分享:http://www.dlmjj.cn/article/dppedhc.html