標籤:style blog http color os io 使用 java ar
一、首先我們來瞭解下指令API
| 屬性 |
含義 |
| restrict |
申明標識符在模版中作為元素,屬性,類,凝視或組合,怎樣使用 |
| priority |
設定模版中相對於其它標識符的運行順序 |
| Template |
指定一個字串式的內嵌模版,假設你指定了模版是一個URL,那麼是不會使用的 |
| tempateUrl |
指定URL載入的模版,假設你已經指定了內嵌的模版字串,那麼它不會使用的 |
| Replace |
假設為真,替換當前元素,假設是假或未指定,拼接到當前元素 |
| Transclude |
移動一個標識符的原始位元組帶你到一個新模版的位置 |
| Scope |
為這個標識符建立一個新的範圍,而不是繼承父範圍 |
| Controller |
建立一個控制器通過標識符公開通訊API |
| Require |
當前標識符須要另外一個標識符提供正確的函數功能 |
| Link |
通過代碼改動目標DOM元素的執行個體,加入事件監聽,建立資料繫結 |
| Compile |
通過標識符拷貝編程改動DOM模版 |
在這裡,我們簡單的瞭解下每一個屬性的含義及其簡單的作用,在後面我們將會通過一些勵志來解釋
接下來,我們來瞭解下指令定義對象
restrict:restrict屬性同意為標識符指定聲明樣式,也就是說它能夠作為元素名,屬性,類或凝視。我們能夠使用一個字串來代表下表中的每一個標誌,從而指定
一個或者多個聲明樣式
| 標誌 |
樣式 |
示範範例 |
| E |
Element |
<my-menu title=‘products‘></my-menu> |
| A |
Attribute |
<div my-menu=‘products‘></div> |
| C |
Class |
<div class=‘my-menu:products‘></div> |
| M |
Comment |
<!--directive:my-menu products--> |
假設你希望標識符作為元素後者屬性,你能夠傳遞EA作為restrict的字串
假設省略了restrict屬性,預設就是A,具體請看angular文檔
Priorities:為應用程式指定順序,數值越大就越先執行,預設是為零,普通情況下無需設定優先權
Templates:在建立組件時,angular同意你在模版中替換和封裝元素中的內容,假設你想建立例如以下的標籤視圖
不是使用一串<div><ul><li><a>等元素來實現,而是能夠通過自己定義建立標識符<tab-set><tab>,分別聲明每一個頁簽的結構,可能假設下
<tab-set><tab title='Home'><p>Welcome home!</p></tab><tab title='Preferences'><!-- preferences UI goes here --></tab></tabset>
同一時候,你也可通過控制器為title和頁簽內容進行資料繫結,並用這樣的方式做出菜單,手風琴,彈窗,對話方塊或其它應用需求
接下來,讓我們來看看temp拉特或者templateUrl屬性,指定替換DOM元素。在上表中,我們看到template能夠用來設定模版內容的字串,
templateUrl用於指定將被載入的server檔案,正如接下來看到的示範範例,我們能夠預緩衝這些模版,一遍降低get請求數,提高效能
<html lang='en' ng-app='app'>...<body><hello></hello></body>...
建立<hello></hello>標籤替換<div>hi there</div>,replace設定為true同意拼接內容到元素上,設定replace成為true
var appModule = angular.module('app', []);appModule.directive('hello', function() {return {restrict: 'E',template: '<div>Hi there</div>', replace: true};});
在載入到瀏覽器後,我們會看到hi there,通過查看頁面原始碼,我們還是會看到<hello></hello>可是假設你檢查產生代碼(chrome,右擊hi htere,選擇檢查元素)你會看到
<body><div>Hi there</div></body>
<hello></hello>已經被模版中的<div>替換。
而相對於使用template 輸入html到字串中不是非常有意義,一般我們都會使用templateUrl,進行設定適當的頭部緩衝
var appModule = angular.module('app', []);appModule.directive('hello', function() {return {restrict: 'E',templateUrl: 'helloTemplate.html', replace: true};});
在helloTemplate.html中,我們須要寫入
<div> Hi there</div>
假設你使用chrome瀏覽器,同源策略會組織可能會導致遇到一個錯誤“Origin null is not allowed by Access-Controll-Allow-Origin”.這裡你有兩種可選方式
1.通過server載入應用
2.chrome 中設定一個標誌,通過命令列‘chrome-allow-file-access-from-files’解決
然後通過templateUrl載入檔案,會使使用者等待知道載入後看到標識符,假設你希望第一次頁面載入時就載入模版,你能夠在script標籤中讓其作為頁面的一部分,例如以下
<script type='text/ng-template' id='helloTemplateInline.html'><div>Hi there</div></script>
這裡的id屬性很重要,由於是URL鍵,angular用它來儲存模版,你應該在標識符的templateUrl中使用id來指定插入那個模版
還有我們能夠通過$http或其它幾種機制載入模版,然後直接設定到angular所使用的$templateCache對象中,並可通過run函數調用它,使其在標識符執行之前讓這個模版在
緩衝中可用
var appModule = angular.module('app', []);appModule.run(function($templateCache) {$templateCache.put('helloTemplateCached.html', '<div>Hi there</div>');});appModule.directive('hello', function() {return {restrict: 'E',templateUrl: 'helloTemplateCached.html', replace: true};});
Transclusion(嵌入包括)
通過transclude屬性移動原始的內容到新模版中,當設定成為true時,標識符會刪除原來的內容,並通過ng-transclude標識符使它又一次插入到模版中
採用transclusion方式改動示範範例:
appModule.directive('hello', function() {return {template: '<div>Hi there <span ng-transclude></span></div>', transclude: true};});
應用在:
<div hello>Bob</div>
我們會看到‘Hi there Bob.’
編譯和連結函數
儘管插入模版是實用,可是在不論什麼標識符真正有意義的工作發生在編譯活著連結功能裡
編譯和連結的功能就是angular為引用建立即時視圖的後兩階段,讓我們來看下angular初始化過程的高層次視圖,依照次序
【1】指令碼載入:載入angular,尋找ng-app標識符找到應用綁定
【2】編譯階段:在這一階段,angular便利DOM標誌模版中全部注冊的標誌,對於每一個標識符,基於標識符規則(template,replace,transclude等等)改造DOM,然後
假設編譯函數存在就調用它,結果一個編譯的template函數,它會調用全部的標識符搜集的link韓素
【3】連結階段:為了讓視圖動起來,angular為每一個標識符執行link函數,link函數通常在DOM或模型上建立監聽器,這些監聽器讓視圖和模型始終保持一致
因此到了編譯階段,它處理轉換了模版,連結階段,它處理了改動視圖中的資料,沿著這些思路,標識符中表一功能和連結功能主要差別就是連結功能轉換了模版自身,而串連功能在模型和視圖上建立了動態連結,就是在第二階段,範圍scpoes被附加到了編譯過程的link功能上,通過資料繫結,標識符變活了
二、範圍
擷取範圍scope的三種選擇
1.標識符DOM元素中已經存在的範圍
2,建立一個繼承封閉的控制器範圍的新範圍,以便讀取結構樹範圍的全部值。
3.獨立作用於,從父類中不繼承不論什麼屬性,當你須要隔離這個標識符的操作和父類範圍時,建立可從用的組建來使用這個選項
我們能夠用例如以下文法類建立這些範圍配置
| 已有範圍 |
scope:false(假設沒有指定,這就是預設值) |
| 新範圍 |
scope:true |
| 獨立範圍 |
scope:{屬性名稱次和綁定風格} |
當你建立一個獨立範圍時,預設情況下不能訪問父類範圍的模型,但我們能夠通過指定須要的屬性傳遞到標識符
注意:儘管獨立範圍並沒有繼承模型屬性,但他們仍然是父範圍的子節點,並$parent指向父類
我們能夠通過標識符屬性的鍵值對父類傳遞指定的屬性給獨立範圍,這裡有三種可行的方式從父範圍傳遞資料,我們稱這些傳遞資料方式叫做“繫結原則”,你能夠為這個屬性名稱指定一個本地別名
沒有別名的文法例如以下:
scope: { attributeName1: 'BINDING_STRATEGY',attributeName2: 'BINDING_STRATEGY', …}
用別名的格式例如以下:
scope: { attributeAlias: 'BINDING_STRATEGY' + 'templateAttributeName',…}
| 符號 |
意義 |
| @ |
傳遞字串屬性,你能夠通過使用改寫{{}}屬性值從粉筆範圍中進行資料繫結 |
| = |
資料繫結屬性在標識符父範圍的屬性中 |
| & |
傳遞一個來自父範圍的函數,稍後調用 |
在這我們用一個詳細範例上的變化來說明它們,比方我們想建立一個expander標識符,展示一個標題列,當點擊時擴充顯示額外內容
關閉的時候
開啟的狀態
代碼例如以下:
<div ng-controller='SomeController'><expander class='expander' expander-title='title'>{{text}}</expander></div>
控制器代碼:
function SomeController($scope) {$scope.title = 'Click me to expand';$scope.text = 'Hi there folks, I am the content+ 'that was hidden but is now shown.';}然後我們編寫標識符
angular.module('expanderModule', []).directive('expander', function(){return {restrict: 'EA', replace: true,transclude: true,scope: { title:'=expanderTitle' }, template: '<div>' +'<div class="title" ng-click="toggle()">{{title}}</div>' +'<div class="body" ng-show="showMe" ng-transclude></div>' +'</div>',link: function(scope, element, attrs) {scope.showMe = false;scope.toggle = function toggle() {scope.showMe = !scope.showMe;}}}});
樣式:
.expander {border: 1px solid black;width: 250px;}.expander > .title {background-color: black;color: white; padding: .1em .3em; cursor: pointer;}.expander > .body {padding: .1em .3em;}
元素的功能
| 功能名 |
|
| Restrict:EA |
描寫敘述調用標識符為元素或屬性,也就是<expander>..</expander>或 <div expander>...</div> |
| Replace:true |
用提供的模版替換原來的元素 |
| Transclude:true |
移動原始元素內容到提供的模版中的另外一個地方 |
| Scope:{title:=expanderTitle}} |
建立一個叫title的本地範圍屬性,它是用來資料繫結到expander-title 屬性中聲明的parent-scope屬性,這裡,為了方便expanderTitle沖命名 為title,因為expanderTitle在模版中,我們飆血範圍 scope:{expanderTitle:‘=‘}來引用它,但在這個情境中,其它標識符也 有一個title屬性,為了防止引起歧義,我們將其重新命名 |
| Template:<div>+ |
為標識符提供即將插入的模版,注意,我們使用ng-click和ng-show 來展示或隱藏自身,ng-transclude來申明原始的內容將何去何從, 同一時候注意嵌入的內容能夠訪問父範圍,而不是封閉標識符的 範圍 |
| Link: |
建立showMe模型,跟蹤expander的開啟和關閉狀態,然後當使用者點擊title div時,調用定義的toggle函數 |
三、操作DOM元素
| 函數 |
描寫敘述 |
| Controller(name) |
與控制器直接進行通訊,這個函數返回綁定在元素上的控制器 假設這個元素不存在,它會遍曆DOM,然後尋找近期的父控制 器取代,假設參數名字是可選的,用於指定允許元素上其它 標識符名稱,假設提供了,則返回標識符上的控制器,這個名字 應該使用駝峰式,也就是說用ngModel取代ng-model |
| Injector() |
擷取當前元素或者父元素的注入器,同意在這些模組中尋找依賴 |
| Scope() |
返回當前元素或者近期父元素的範圍 |
| inHeritedData() |
和jquery的data()函數一樣,inheritedData()以封閉的方式設定以及擷取元素上的 資料,除了從當前元素擷取資料,它會便利DOM尋找 |
以下範例,我們不用ng-show和ng-click又一次實現之前expander示範範例
angular.module('expanderModule', []).directive('expander', function(){return {restrict: 'EA', replace: true, transclude: true,scope: { title:'=expanderTitle' }, template: '<div>' +'<div class="title">{{title}}</div>' +'<div class="body closed" ng-transclude></div>' +'</div>',link: function(scope, element, attrs) {var titleElement = angular.element(element.children().eq(0));var bodyElement = angular.element(element.children().eq(1));titleElement.bind('click', toggle);function toggle() {bodyElement.toggleClass('closed');}}}});
在上面我們從模版中移除了ng-click和ng-show標識符,然而,當使用者點擊expander標題時候,仍然運行預期的操作,我們從tittle元素上建立了一個jqLite元素,然後把toggle函數綁定到click事件上作為它的回調,在toggle函數,我們在expander body元素上調用toggleClass()
來加入或移除closed的類,我們會設定這個元素class設定成的displat:none
.closed {display: none;}
angularjs入門學習【指令篇】