欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

AngularJS 中的指令實(shí)踐開(kāi)發(fā)指南(一)

 更新時(shí)間:2016年03月20日 20:44:08   投稿:mrr  
指令(Directives)是所有AngularJS應(yīng)用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要?jiǎng)?chuàng)建應(yīng)用特定的指令。這篇教程會(huì)為你講述如何自定義指令,以及介紹如何在實(shí)際項(xiàng)目中使用

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

概述

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

jQuery視角

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

<input type="text" />

或者是這樣:

<input type="text" />

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

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

一個(gè)Angular指令可以有以下的四種表現(xiàn)形式: 1. 一個(gè)新的HTML元素(<data-picker></data-picker>) 2. 元素的屬性(<input type=”text” data-picker/>) 3. CSS class(<input type=”text” class=”data-picker”/>) 4. 注釋(<!–directive:data-picker –>) 當(dāng)然,我們可以控制我們的指令在HTML中的表現(xiàn)形式。下面我們來(lái)看一下AngularJS中的一個(gè)典型的指令的寫(xiě)法。指令注冊(cè)的方式與 controller 一樣,但是它返回的是一個(gè)擁有指令配置屬性的簡(jiǎn)單對(duì)象(指令定義對(duì)象) 。下面的代碼是一個(gè)簡(jiǎn)單的 Hello World 指令。

var app = angular.module('myapp', []);
app.directive('helloWorld', function() {
return {
restrict: 'AE',
replace: 'true',
template: '<h3>Hello World!!</h3>'
};
});

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

<hello-world/>
//OR
<hello:world/>

或者,以一個(gè)屬性的方式使用:

<div hello-world></div>
//OR
<div hello:world/>

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

<div data-hello-world></div>
//OR
<div x-hello-world></div>

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

restrict – 這個(gè)屬性用來(lái)指定指令在HTML中如何使用(還記得之前說(shuō)的,指令的四種表示方式嗎)。在上面的例子中,我們使用了 ‘AE'。所以這個(gè)指令可以被當(dāng)作新的HTML元素或者屬性來(lái)使用。如果要允許指令被當(dāng)作class來(lái)使用,我們將 restrict 設(shè)置成 ‘AEC'。

template – 這個(gè)屬性規(guī)定了指令被Angular編譯和鏈接(link)后生成的HTML標(biāo)記。這個(gè)屬性值不一定要是簡(jiǎn)單的字符串。template 可以非常復(fù)雜,而且經(jīng)常包含其他的指令,以及表達(dá)式({{ }})等。更多的情況下你可能會(huì)見(jiàn)到 templateUrl, 而不是 template。所以,理想情況下,你應(yīng)該將模板放到一個(gè)特定的HTML文件中,然后將 templateUrl 屬性指向它。
replace – 這個(gè)屬性指明生成的HTML內(nèi)容是否會(huì)替換掉定義此指令的HTML元素。在我們的例子中,我們用 <hello-world></hello-world>的方式使用我們的指令,并且將 replace 設(shè)置成 true。所以,在指令被編譯之后,生成的模板內(nèi)容替換掉了 <hello-world></hello-world>。最終的輸出是 <h3>Hello World!!</h3>。如果你將 replace 設(shè)置成 false,也就是默認(rèn)值,那么生成的模板會(huì)被插入到定義指令的元素中。
打開(kāi)這個(gè) plunker,在”Hello World!!”右鍵檢查元素內(nèi)容,來(lái)更形象地明白這些。

Link函數(shù)和Scope

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

<body ng-controller="MainCtrl">
<input type="text" ng-model="color" placeholder="Enter a color" />
<hello-world/>
</body>

修改后的 helloWorld 指令如下:

app.directive('helloWorld', function() {
return {
restrict: 'AE',
replace: true,
template: '<p style="background-color:{{color}}">Hello World',
link: function(scope, elem, attrs) {
elem.bind('click', function() {
elem.css('background-color', 'white');
scope.$apply(function() {
scope.color = "white";
});
});
elem.bind('mouseover', function() {
elem.css('cursor', 'pointer');
});
}
};
});

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

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

link函數(shù)主要用來(lái)為DOM元素添加事件監(jiān)聽(tīng)、監(jiān)視模型屬性變化、以及更新DOM。在上面的指令代碼片段中,我們添加了兩個(gè)事件, click,和 mouseover。click 處理函數(shù)用來(lái)重置 <p> 的背景色,而 mouseover 處理函數(shù)改變鼠標(biāo)為 pointer。在模板中有一個(gè)表達(dá)式 {{color}},當(dāng)父scope中的 color 發(fā)生變化時(shí),它用來(lái)改變 Hello World 文字的背景色。 這個(gè) plunker 演示了這些概念。

compile函數(shù)

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

tElement – 指令所在的元素
attrs – 元素上賦予的參數(shù)的標(biāo)準(zhǔn)化列表
要注意的是 compile 函數(shù)不能訪問(wèn) scope,并且必須返回一個(gè) link 函數(shù)。但是如果沒(méi)有設(shè)置 compile 函數(shù),你可以正常地配置 link 函數(shù),(有了compile,就不能用link,link函數(shù)由compile返回)。compile函數(shù)可以寫(xiě)成如下的形式:

app.directive('test', function() {
return {
compile: function(tElem,attrs) {
//do optional DOM transformation here
return function(scope,elem,attrs) {
//linking function here
};
}
};
});

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

指令是如何被編譯的

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

改變指令的Scope

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

一個(gè)子scope – 這個(gè)scope原型繼承子父scope。
一個(gè)隔離的scope – 一個(gè)孤立存在不繼承自父scope的scope。
這樣的scope可以通過(guò)指令定義對(duì)象中 scope 屬性來(lái)配置。下面的代碼片段是一個(gè)例子:

app.directive('helloWorld', function() {
return {
scope: true, 
// use a child scope that inherits from parent
restrict: 'AE',
replace: 'true',
template: '<h3>Hello World!!</h3>'
};
});

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

app.directive('helloWorld', function() {
return {
scope: {}, 
// use a new isolated scope
restrict: 'AE',
replace: 'true',
template: '<h3>Hello World!!</h3>'
};
});

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

關(guān)于AngularJS 中的指令實(shí)踐指南(一),小編就給大家介紹到這里,下面文章講給大家介紹angularjs中的指令實(shí)踐開(kāi)發(fā)指南二(二),希望對(duì)大家有所幫助!

相關(guān)文章

  • angularjs 中$apply,$digest,$watch詳解

    angularjs 中$apply,$digest,$watch詳解

    這篇文章主要介紹了angularjs 中$apply,$digest,$watch詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 關(guān)于Angular2 + node接口調(diào)試的解決方案

    關(guān)于Angular2 + node接口調(diào)試的解決方案

    這篇文章主要給大家介紹了關(guān)于Angular2 + node接口調(diào)試的解決方案,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-05-05
  • Angular利用內(nèi)容投射向組件輸入ngForOf模板的方法

    Angular利用內(nèi)容投射向組件輸入ngForOf模板的方法

    本篇文章主要介紹了Angular利用內(nèi)容投射向組件輸入ngForOf模板的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 詳解Angular2中的編程對(duì)象Observable

    詳解Angular2中的編程對(duì)象Observable

    大家都是在Reactive Extensions for Javascript誕生于幾年前,隨著angular2正式版的發(fā)布,它將會(huì)被更多開(kāi)發(fā)者所認(rèn)知。這篇文章我們來(lái)詳細(xì)介紹RxJs提供的Observable對(duì)象,有需要的朋友們可以參考借鑒。
    2016-09-09
  • 詳解Angular.js中$http攔截器的介紹及使用

    詳解Angular.js中$http攔截器的介紹及使用

    攔截器就是在目標(biāo)達(dá)到目的地之前對(duì)其進(jìn)行處理以便處理結(jié)果更加符合我們的預(yù)期,下面這篇文章主要給大家介紹了關(guān)于Angular.js中$http攔截器的介紹及使用的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考學(xué)習(xí)。
    2017-07-07
  • Angular2中如何使用ngx-translate進(jìn)行國(guó)際化

    Angular2中如何使用ngx-translate進(jìn)行國(guó)際化

    本篇文章主要介紹了Angular2中使用ngx-translate進(jìn)行國(guó)際化,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示示例

    通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示示例

    本篇文章主要介紹了通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • 簡(jiǎn)介可以自動(dòng)完成UI的AngularJS工具angular-smarty

    簡(jiǎn)介可以自動(dòng)完成UI的AngularJS工具angular-smarty

    這篇文章主要介紹了簡(jiǎn)介可以自動(dòng)完成UI的AngularJS工具angular-smarty,包括其中隔離作用域綁定指令符和promise的使用,需要的朋友可以參考下
    2015-06-06
  • AngularJS發(fā)送異步Get/Post請(qǐng)求方法

    AngularJS發(fā)送異步Get/Post請(qǐng)求方法

    今天小編就為大家分享一篇AngularJS發(fā)送異步Get/Post請(qǐng)求方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 利用VS Code開(kāi)發(fā)你的第一個(gè)AngularJS 2應(yīng)用程序

    利用VS Code開(kāi)發(fā)你的第一個(gè)AngularJS 2應(yīng)用程序

    這篇文章主要給大家介紹了關(guān)于利用VS Code如何開(kāi)發(fā)你的第一個(gè)AngularJS 2應(yīng)用程序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友下面來(lái)一起看看吧。
    2017-12-12

最新評(píng)論