angular自定義指令詳解

指令(directive)是angular里面最核心也是最難懂的東西,在慕課網看了下大漠窮秋老濕的視頻,自己百度半天做了一些小test,總算把一切都搞明白了。

先列出學習來源:

指令中controller和link的區別:http://www.cnblogs.com/CreateMyself/p/5568202.html

?

angular視頻教程:http://www.imooc.com/learn/156

?

指令中的隔離 Scope :https://blog.coding.net/blog/angularjs-directive-isolate-scope

?

angular學習筆記:https://www.zouyesheng.com/angular.html#toc68

?

?

一、指令的創建:

首先你得先創建一個module:

var module1 = angular.module('module1',[]);
angular.bootstrap(document.body,['module1']);

然后你還得有一個對應的controller:

var module1 = angular.module('module1',[]);module1.controller('ctl1', function($scope) {$scope.content = 'i\'m, module 1';$scope.name = 'module1';$scope.save = function() {console.log('is function save');};
});
angular.bootstrap(document.body,['module1']);
?

?

?

然后你就可以安心的創建指令了:

// 銜接上面的代碼
m1.directive('testDirective', function() {// 將對象return出去return{restrict: 'E',// 指令類型 E:element A:attribute M:comment C: classtemplate: '<div>我是指令生成的內容</div>';replace: true, //使用模板替換原始標記 指令內原本的數據將被清空 } });
angular.bootstrap(document.body,['module1']);
?

對應的html可以這樣寫:

<body><div  ng-controller="ctl1">{{content}}<test-directive>這是原本的內容</test-directive></div>
</body>

以上代碼需要注意一下幾點:

1.我們定義的指令名稱是testDirective,但是在html中要寫成test-directive。

2.我們把指令里面的代碼都放在了function中的return里面,其實return出去的內容就是整個指令對象。

3.angular.bootstrap(document.body,['module1']);相當于我們在html中使用ng-app指令。推薦使用bootstarp而不是ng-app;

?

?

二、指令的屬性

指令的屬性如下:

  • name
  • priority
  • terminal
  • scope
  • controller
  • require
  • restrict
  • template
  • templateUrl
  • replace
  • transclude
  • compile
  • link

其中的name、priority、terminal不做詳細的介紹。

name就是指令名,對應上面代碼中的testDirective,priority多個指令設置在同一個元素上的執行優先級,執行順序從低至高:1>2>3.priority的值為正整數,比如priority: 1,

terminal,?true/false 如果為true,同一個元素上的其他指令的優先級高于本指令,其他指令將停止執行

priority和terminal傳送門

1.restrict屬性

angular內置的一些指令,比如ng-app,ng-click之類的,都是以html元素的屬性(atrrbile)的形式來實現的,我在使用ionic框架的時候,里面有很多自定義的標簽、比如:<ion-content></ion-content>。這也是一個指令,他是通過html元素(element)來實現的。除了這兩個之外,指令還支持class(html標簽的class屬性)、commment(html中的注釋)來實現。

在JS代碼中,restrict可以有以下賦值:

 restrict: 'AE',// 指令類型  E:element A:attribute M:comment C: class

可以是多個restrict: 'AEMC',也可以是一個restrict: 'E'。在html中對應的寫法為:

其中注釋: <!-- 兩邊一定要留空格,不然什么都不會發生?-->

?

?

?

?

2.template和templateUrl

同一個指令中只能templatetemplateUrl只能選其一。

template為模板內容。即你要在指令所在的容器中插入的html代碼。

template屬性接收一個字符串,類似這樣:

  template: '<div>我是指令生成的內容</div>';

?

你也可以將整個template寫得很復雜,但是,復雜的代碼非常不易維護。并且你還得換行,得用字符串拼接每一行。

當你的tamplate超出10行就會顯得辣眼睛,過長的template建議使用templateUrl代替。

?

?

templateUrl為從指定地址獲取模板內容。即你要在指令所在的容器中插入的一個.html文件。

有了templateUrl我們就可以將想實現的內容寫成一個單獨的html模版,在需要的地方插入,使用起來會很舒服。

這里的templateUrl類似于JSP中的include,angular也有一個ng-include指令。

具體的詳細請點連接:http://www.ziqiangxuetang.com/angularjs/angularjs-include.html

?

?

3.replace和transclude

replace:是否用模板替換當前元素。true : 將指令標簽替換成temple中定義的內容,頁面上不會再有<my-directive>標簽;false :則append(追加)在當前元素上,即模板的內容包在<my-directive>標簽內部。默認false。

transculde:是否使用ng-transculde來包含html中指令包含的原有的內容,接收兩個參數true/false

先上例子:replace

var app = angular.module("app", []).directive("hello", function () {var option = {restrict: "AECM",template: "<h3>Hello, Directive</h3>",replace: true  //這里replace為true,所以原來的內容會被template代替};return option;})
<html><head></head><body><hello>我是原來的內容</hello> ===> 變成<h3>Hello, Directive</h3>
      如果replace為false ===><hello><h3>Hello, Directive</h3></hello>
</body> 
</html>

transclude:

var app = angular.module("app", []).directive("hello", function () {var option = {restrict: "AECM",template: "<h3>Hello, Directive</h3><span ng-transclude></span>",transculde: true  //這里transculde為true,所以原來的內容會被放在有ng-transclude屬性的標簽內
        };return option;})
<html><head></head><body><hello>我是原來的內容</hello> ===> 變成<hello><h3>Hello, Directive</h3><span ng-transclude>我是原來的內容</span></hello>
</body> 
</html>

?

4.指令中的scope

directive 默認能共享父 scope 中定義的屬性,例如在模版中直接使用父 scope 中的對象和屬性。通常使用這種直接共享的方式可以實現一些簡單的 directive 功能。

但是,當你要創建一個可以重復使用的directive的時候,就不能依賴于父scope了,因為在不同的地方使用directive對應的父scope不一樣。

所以你需要一個隔離的scope,我們可以向下面這樣來定義我們的scope。

module1.directive("testDirective", function () {return {scope: {value: '提莫隊長正在待命!'},template: 'Say:{{value}}'}
});             

這樣就很方便的將我們directive的上下文scope給定義出來了,但是,如果我想將父scope中的屬性傳遞給directive的scope怎么辦呢?

directive 在使用隔離 scope 的時候,提供了三種方法同隔離之外的地方交互:

  • @ 綁定一個局部 scope 屬性到當前 dom 節點的屬性值。結果總是一個字符串,因為 dom 屬性是字符串。
  • & 提供一種方式執行一個表達式在父 scope 的上下文中。如果沒有指定 attr 名稱,則屬性名稱為相同的本地名稱。
  • = 通過 directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間建立雙向綁定。

以上三種方式都要在directive的attr屬性中進行賦值。上面的話理解起來比較困難,我根據自己的理解做了一下修改:

@:只能綁定字符串,所以一些簡單的繼承父scope的屬性使用@
=: 需要實現雙向數據綁定的時候使用=
&: 提供一種方式執行一個表達式在父scope的上下文中,即使用于將父scope中的函數綁定在指令的scope中

以上的理解也許有些偏頗,歡迎指正。

(1)先說@

app.controller("ctl1", function ($scope) {$scope.name = "hello world";}).directive("testDirective", function () {return {scope: {name: "@"},template: 'Say:{{name}} <br>改變隔離scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">'}
})
<div ng-controller="ctl1"><div><div>父scope:<div>Say:{{name}}<br>改變父scope的name:<input type="text" value="" ng-model="name"/></div></div><div>隔離scope:這個顯示為hello world<div test-directive name="{{name}}"></div></div><div>隔離scope(不使用{{name}}這個就直接顯示為name了):<div test-directive name="name"></div> </div></div>

我們在test-directive指令所在的div上面,增加了一個name屬性,要使用雙花括號來給屬性賦值。也可以寫成nameCopy:'@nameForCtl',這樣寫,在給directive中的scope的屬性賦值的時候,獲取查詢@后面的name這個標識對應的屬性的值(這里nameForCtl在js中是駝峰寫法,同樣的在html中對應的屬性名應該寫成name-for-ctl)。不是很推薦這種寫法,感覺有點多余。

(2)=

上一個例子中,我們使用name="{{name}}"的形式來傳遞父scope 的屬性對應的值,so,我們只是把對應的值傳遞給了directive的scope,當我想實現在directive中改變父scope傳遞過來的值時,父scope中的值也對應的改變,顯然用@這種方法走不通。

這時=就派上用場了。

 app.controller("ctl1", function ($scope) {$scope.user = {name: 'hello',id: 1};}).directive("testDirective", function () {return {scope: {user: "="},template: 'Say:{{user.name}} <br>改變隔離scope的name:<input type="buttom" value="" ng-model="user.name"/>'}})
<div ng-controller="ctl1"><div>父scope:<div>Say:{{user.name}}<br>改變父scope的name:<input type="text" value="" ng-model="user.name"/></div></div><div>隔離scope:<div isolated-directive user="user"></div></div><div>隔離scope(使用{{name}},這個會報錯):<div isolated-directive user="{{user}}"></div> </div>
</div>

這一個例子和上一個例子不同的地方就是屬性賦值的時候,一個應該使用{{}},一個不該使用。=為了實現雙向數據綁定,angular會使用‘=’對應的屬性的值與父scope中的屬性進行匹配,然后傳遞給diractive中的scope。至于實現的細節和原理,這里我就不說了(其實是不大清楚)。

(3)&

& 方式提供一種途經使directive 能在父 scope 的上下文中執行一個表達式。此表達式可以是一個 function。其實說白了,就是可以使用在父scope中定義的函數。

比如:當你寫了一個 directive,當用戶點擊按鈕時,directive 想要通知 controller,controller 無法知道 directive 中發生了什么,也許你可以通過使用 angular 中的 event 廣播來做到,但是必須要在 controller 中增加一個事件監聽方法。
最好的方法就是讓 directive 可以通過一個父 scope 中的 function,當 directive 中有什么動作需要更新到父 scope 中的時候,可以在父 scope 上下文中執行一段代碼或者一個函數。

 app.controller("ctl1", function ($scope) {$scope.value = "hello world";$scope.click = function () {$scope.value = Math.random();};}).directive("testDirective", function () {return {scope: {action: "&"},template: '<input type="button" value="在directive中執行父scope定義的方法" ng-click="action()"/>'}})
<div  ng-controller="ctl1"><div>父scope:<div>Say:{{value}}</div></div><div>隔離scope:<div isolated-directive action="click()"></div></div>
</div>

在上面的例子中,我們的屬性action賦值為一個方法:action="click()",這樣一寫,一眼就看出來是個什么東西了,好像也沒什么好解釋的。

?

5.controller、require以及link

?這三個涉及到指令的執行過程,本人暫時還沒有比較完全的理解,所以這里只能讓大家去看別人寫的博客了(原諒我太笨);

連接在頂部。嗯。 ? ?↑點擊返回頂部

轉載于:https://www.cnblogs.com/ermu-learn/p/5913760.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457880.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457880.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457880.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

delphi7aes加密解密與java互轉_跨語言(java vs python vs nodejs)的RSA加解密問題探討

多次被問到這樣的問題&#xff1a;java服務端的rsa加密操作已經完成&#xff0c;返回一個16進制的字符串給python平臺&#xff0c;但是在python進行私鑰解密的時候發現行不通。。。。前端python加密&#xff0c;后端用java解密&#xff0c;解不出來還有諸如nodejs從理論上來說&…

類的定義、成員定義修飾符

類的定義 修飾符含義1無或internal 只能在當前項目中訪問類&#xff0c;其它項目引用后也無法訪問2public 可以任何地方訪問類3abstract 不能實例化&#xff0c;只能供繼承之用4sealed 不能供派生之用&#xff0c;只能實例化5internal abstract136public abstract237intern…

設備模型3

在上一篇分析中&#xff0c;多次提到了SYSFS&#xff0c;這是個什么東西&#xff1f;這可是個很大的TOPIC&#xff0c;關于它的講述可以寫本書&#xff0c;但是我們暫時的目標不是要完全啃投它所有的東西&#xff0c;沒時間&#xff0c;沒精力&#xff0c;我們只要掌握我們需要…

浪潮之巔讀后感

這幾天看到一本非常好的書《浪潮之巔》。浪潮&#xff0c;指的是時代的大潮。而浪潮之巔&#xff0c;顧名思義就是指站在時代潮流的巔峰&#xff0c;引領時代潮流&#xff0c;扛起發展大旗。而本書就是在介紹各大處在浪潮之巔的IT公司的歷史及發展。 書中有句話說得好&#xff…

利用dft的定義計算dft的matlab程序_CP2K教程系列之靜態計算(Pymatflow篇)

本系列CP2K教程是《CP2K菜根譚》的升級版&#xff0c;在舊版基礎上添加了如何結合Pymatflow工具簡化計算流程的內容。話不多說&#xff0c;本文將為您帶來CP2K系列教程中的靜態計算部分。靜態計算設置靜態計算是大多數人接觸第一性原理計算后第一次運行的計算類型。很多其它類型…

機器學習:最大似然估計與最大后驗概率估計

在機器學習領域&#xff0c;概率估計是經常用到的一種模型&#xff0c;而概率估計中&#xff0c;我們經常會看到兩種估計模型&#xff0c;一種是最大似然估計&#xff0c;即 Maximum likelihood&#xff0c; 另外一種就是最大后驗概率估計&#xff0c;即 Maximum posterior &am…

ubuntu14.04安裝git

參考教程&#xff1a;git介紹&#xff1a;安裝&#xff0c;使用&#xff0c;創建分支 安裝的方法有兩種&#xff0c;一種直接是通過ubuntu的APT安裝&#xff0c;這種方法最簡便&#xff0c;缺點是版本可能不是最新的。所有還有另一種方法是下載源碼進行安裝&#xff0c;這種能…

微軟是如何戲耍程序員們的

2019獨角獸企業重金招聘Python工程師標準>>> 別用微軟的東西。商業目的性太強&#xff0c;千萬別被微軟牽著鼻子走&#xff0c;血淋淋的教訓。微軟推出的垃圾多了去了。它什么都想做&#xff0c;很多都沒做好&#xff1a; MFC&#xff1a;Win31時代出生&#xff0c;…

3d立體相冊特效html網頁代碼_新聞類網頁正文通用抽取器

項目起源開發這個項目&#xff0c;源自于我在知網發現了一篇關于自動化抽取新聞類網站正文的算法論文——《基于文本及符號密度的網頁正文提取方法》這篇論文中描述的算法看起來簡潔清晰&#xff0c;并且符合邏輯。但由于論文中只講了算法原理&#xff0c;并沒有具體的語言實現…

ubuntu14.04安裝 R16 Tina Linux SDK

第一步&#xff1a;由于是14.04系統所以這樣$sudo -i $cd /etc/apt/sources.list.d $echo "deb http://old-releases.ubuntu.com/ubuntu/ raring main restricted universe multiverse" > ia32-libs-raring.list $apt-get update $apt-get install ia32-libs $r…

分答

用戶在分答上可以自我介紹或描述擅長的領域&#xff0c;設置付費問答的價格&#xff0c;其他用戶感興趣就可以付費向其提問。分答的收入分配機制增加了信息的價值&#xff0c;分答中信息接收者被區分成了兩種身份。首先提問的人是一種付費懸賞模式&#xff0c;當回答完畢內容沉…

字節數組轉換為圖片_每日一課 | Python 3 TypeError:無法將“字節”對象隱式轉換為str...

將Python 2套接字示例轉換為Python 3whois.py import sysimport sockets socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(("whois.arin.net", 43))s.send((sys.argv[1] "\r\n").encode())response ""while True: data s.re…

php版redis插件,SSDB數據庫,增強型的Redis管理api實例

php版redis插件,SSDB數據庫,增強型的Redis管理api實例 SSDB是一套基于LevelDB存儲引擎的非關系型數據庫&#xff08;NOSQL&#xff09;&#xff0c;可用于取代Redis&#xff0c;更適合海量數據的存儲。另外&#xff0c;rocksdb是FB在LevelDB的二次開發版本&#xff0c;因此也存…

加速度計和陀螺儀數據融合

本帖翻譯自 IMU&#xff08;加速度計和陀螺儀設備&#xff09;在嵌入式應用中使用的指南。這篇文章主要介紹加速度計和陀螺儀的數學模型和基本算法&#xff0c;以及如何融合這兩者&#xff0c;側重算法、思想的討論介紹本指南旨在向興趣者介紹慣性MEMS&#xff08;微機電系統&a…

循環嵌套練習題

//BOSS://讓用戶輸入一個奇數&#xff0c;打印菱形&#xff0c;最長的行內容個數為用戶輸入的個數&#xff0c;并且由英文字母拼接而成//比如用戶輸入了7// A// ABA// ABCBA// ABCDCBA// ABCBA// ABA// A//1、接收并判斷用戶輸入的是不是數字 try{#region 解法一…

python leetcode_leetcode 介紹和 python 數據結構與算法學習資料

for &#xff08;剛入門的編程&#xff09;的高中 or 大學生leetcode 介紹leetcode 可以說是 cs 最核心的一門“課程”了&#xff0c;雖然不是大學開設的&#xff0c;但基本上每一個現代的高水平的程序員都修過這門“課程”&#xff08;或者類似的課程&#xff0c;比如數據結構…

平衡小車卡爾曼濾波算法

最近研究STM32的自平衡小車&#xff0c;發現有兩座必過的大山&#xff0c;一為卡爾曼濾波&#xff0c;二為PID算法。 網上看了很多關于卡爾曼濾波的代碼&#xff0c;感覺寫得真不咋地。一怒之下&#xff0c;自己重寫&#xff0c;不廢話&#xff0c;貼代碼 [pre lang"C&quo…

IOS 為UILabel添加長按復制功能

IOS 為UILabel添加長按復制功能 在iOS中下面三個控件&#xff0c;自身就有復制-粘貼的功能&#xff1a; 1、UITextView 2、UITextField 3、UIWebView UIKit framework提供了幾個類和協議方便我們在自己的應用程序中實現剪貼板的功能。 1、UIPasteboard&#xff1a;我們可以向其…

navicat 的查詢功能

navicat的查詢的位置在&#xff1a; 在編輯器界面寫代碼&#xff0c;代碼完成后點左上角的運行。 代碼&#xff1a; create&#xff08;創建&#xff09; table&#xff08;一個表&#xff09; <xxx>尖括號內的內容必填——我要創建并查詢一個名叫做xxx的表 &#xff08…

c++ sleep函數_Linux 多線程應用中如何編寫安全的信號處理函數

關于代碼的可重入性&#xff0c;設計開發人員一般只考慮到線程安全&#xff0c;異步信號處理函數的安全卻往往被忽略。本文首先介紹如何編寫安全的異步信號處理函數&#xff1b;然后舉例說明在多線程應用中如何構建模型讓異步信號在指定的線程中以同步的方式處理。Linux 多線程…