AngularJs

angular

數據雙向綁定的框架javascript

提供數據綁定,DOM指令。angular,定義了一套規則,開發中就必須遵照規則,這套規則爲項目提供了一套解決方案。css

模塊組件模板元數據數據綁定, 指令服務,依賴注入,控制器過濾器,路由html

clipboard.png

基本概念

啓動/引導

啓動/引導 (Bootstrap)
做用:啓動程序入口(bootstrap方法來引導Anuglar引用程序)
識別應用程序中的根做用域$rootScope
經過依賴注入體系註冊服務的提供商java

屬性型指令

屬性型指令 (Attribute Directive)
是指令分類的一種。
做用:監聽或修改其它HTML元素,屬性,組件的行爲。通常做爲HTML屬性。
例如: ng-controller 當前所在的元素添加控制器。node

組件

組件(Component)
做用:把數據展現到視圖(view),並處理全部的視圖顯示和交互邏輯的Angular類。angularjs

在類中定義組件的應用邏輯 ( 它被用來爲視圖提供支持 ) , 組件經過一些由屬性和方法組成的 API 與視圖交互。npm

組件是Angular系統中最重要的基本構造核心之一。json

clipboard.png

數據綁定

數據綁定(Data Binding)
做用:將數據展現給用戶,用戶操做作出應答。
將這些數據顯示到HTML中,添加事件監聽器,獲取數據變化,更新數據。bootstrap

clipboard.png

在雙向數據綁定中,數據的屬性值會從具備屬性綁定的組件傳到輸入框。經過事件綁定,用戶的修改數據傳回到組件,把屬性值設置爲最新的值。設計模式

Anuglar 在每個JS事件週期中一次性處理全部的數據綁定,它會從組件樹的根部開始,用深度優先的方式! (數據綁定在模板與對應組件的交互中起到了重要做用)

clipboard.png

組件從技術角度上看就是一個指令。組件位置很獨特,並在Angular中位於中心地位。

插值表達式

  • 屬性綁定

  • 事件綁定

  • attribute綁定

  • css類綁定

  • 樣式綁定

  • 基於ngModel的雙向數據綁定

單向綁定 (ng-bind) 和雙向綁定(ng-model)

ng-bind 單項數據綁定 ($scope -> view) 用於數據顯示,簡寫形式 {{}}
區別:頁面沒有加載完畢{{val}} 會直接顯示到頁面,知道Angular渲染該綁定數據.
ng-bind則是在Angular渲染完畢後將數據顯示.

ng-model 雙向數據綁定 ($scope -> view and view -> $scope) ,用戶綁定值會變化的表單元素等.

每次綁定一個東西到 view 上時 AngularJS 就會往 $watch 隊列裏插入一條 $watch,用來檢測它監視的 model 裏是否有變化的東西。

當瀏覽器接收到能夠被 angular context 處理的事件時,$digest 循環就會觸發。$digest 會遍歷全部的 $watch 。

一次更新數據操做,至少會觸發兩次$digest() 循環,$gigest循環的次數達到了10次(超過10次後拋出一個異常,爲了防止無限循環)

依賴注入

依賴注入(Dependency Injection)

須要依賴的緣由:無法控制這實例背後隱藏的依賴。 當不能控制依賴時,類就會變得難以測試。

按需注入,須要才注入。
經過給函數添加形參,使得caller傳入的參數的callee接收的參數邏輯分離,使得函數經過依賴管理系統僅僅須要聲明需呀的協做對象,而不須要知道從哪裏來,如何建立等問題。

依賴注入便是設計模式,同時又是一種機制:當應用程序的一些組件須要另一些組件的時候,使用依賴注入機制來建立被請求的部件並將其注入到發出請求的組件中。

提供類的新勢力的一種方式,負責處理好累所需的所有依賴。大多數依賴都是服務。Angualr使用依賴注入提供所需的組件以及組件所需的服務。

clipboard.png

angular構建應用程序時:定義許多精簡的小部件,每一個小部件只作一件事,而且作好它,而後在運行期把這寫精簡小部件裝配在一塊兒組成應用程序。

依賴注入的核心是:注入器(Injector),這個注入器根據須要返回被依賴的部件。injector.get(token) 方法返回與token(令牌)參數相關的依賴部件。

clipboard.png

令牌是一個Angular中類型.絕大多數類方法都接受類名或字符串。Angular會把這些類名稱和字符串轉換成令牌。當調用injector.get(Foo)時,注入器返回用Foo類生成的令牌所對應的依賴值,該依賴值一般是Foo 類的實例。

注入器(Injector)維護一個令牌與相應依賴值的對照表(map)。若是注入器不能找到一個令牌對應的依賴值,它就會使用提供商(Provider) 來建立一個依賴值.

提供商是建立依賴實例的「菜譜」之一,這個實例會與一個特定的令牌關聯起來。

只有當注入器內部的提供商註冊表中存在於令牌對應的提供商時,注入器才能爲這個令牌建立一個依賴值。

angular會爲每一個注入器註冊不少angular內建提供商。
一般註冊提供商的最佳時間是在應用程序引導(Bootstrap)的時候。

依賴注入滲透在整個框架中,而且被處處使用。
注入器負責維護一個 容器 ,用於存放它建立過的服務實例。
注入器能使用 提供商 建立一個新的服務實例。
提供商 是一個用於建立服務的「配方」。
把 提供商 註冊到注入器。

指令

指令(Directive)
指令是一個Angular類
做用:建立和重塑瀏覽器DOM中的HTML元素,負責與HTML元素的應答系統

指令包括的類別:

  • 組件(Component): 用來把程序邏輯和HTML模板組合起來,渲染出應用程序的視圖。組件通常表示成HTML元素的形式,

  • 屬性型指令:能夠監控和修改其它HTML元素,HTML屬性,DOM屬性,組件等行爲。

  • 結構性指令:負責塑造HTML佈局。通常是經過添加,刪除或操做HTML元素及其子元素來實現的。

注入器

注入器(Injector)
Anuglar依賴注入系統中的一個對象。
做用:從緩存中找到一個"有名字的依賴"或者利用一個已註冊的提供商來建立依賴。

注入器是一個維護服務實例的容器,存放着之前建立的實例。
若是容器中尚未所請求的服務實例,注入器就會建立一個服務實例,而且添加到容器中,而後把這個服務返回給Angular。
當左右服務都被解析並返回時,Angular會以服務爲參數去調用組件的構造函數。

插值表達式

插值表達式(Interolation)

屬性數據綁定的形式:位於雙大括號中的模板表達式會被渲染成文本。

模塊

模塊(Module)
應用程序一般由不少個模塊組裝而成。
模塊導出東西--類,函數,值,供其它模塊引入。
把應用寫成一組模塊,每一個模塊只導出同樣東西。

clipboard.png

模塊:具備單一用途的內聚代碼塊

一個模塊加載器來按需加載模塊並解析模塊的依賴關係。

模塊庫

clipboard.png

有些模塊是其它模塊的庫
Anuglar 自己就是經過npm包發佈的一組模塊庫, 以@angular爲前綴。
每一個庫包含一個 封裝桶 。是公開的外觀層(facade) 包括一些邏輯相關的私有模塊。

管道

管道(Pipe)

管道是一個函數
做用:把輸入值換成輸出值供視圖顯示。

提供商

提供商(Provider)
做用:依賴注入系統依靠提供商來建立依賴實例。
它把一個供查閱用的令牌和代碼關聯到一塊兒,以便建立依賴值。

服務

服務是一個類,具體實現一件事情,具備專一,良好定義的用途。
幾乎任何東西均可以是一個服務。

clipboard.png

結構型指令

添加,刪除或操做元素和其各級子元素來塑造或重塑HTML佈局的指令。

例如:ngIf

模板

模板(Template)
模板是大塊HTML。
做用:渲染視圖
Angular會在指令和組件的支持和持續指導下,渲染視圖。

clipboard.png

裝飾器

裝飾器 (Decorator | Decoration)

裝飾器是一個 函數,這個函數將元數據添加到類,類成員(屬性,方法)和函數上。

angular 使用自身一套裝飾器來實現應用程序各個部分之間的相互操做。

基礎指令

ng-app

應用程序的指令,一個程序中必需要有該指令

<body ng-app></body>

ng-model

數據綁定的指令,將數據綁定到應用程序中

<input type="text" ng-model="msg" />

ng-bind

綁定數據,它的簡寫方式直接在元素中{{key}}

<div>{{ msg }}</div>

當頁面加載完畢,angularjs啓動起來,首先回去頁面中尋找ng-app指令,找到後初始化應用程序。
ng-app告知angular這個應用是綁定那個DOM元素,也就是程序初始化的元素時body,因此之後綁定的指令可以生肖的只能在ng-app所在的元素中
angularjs找到ng-model指令,它將該指令對應數據綁定在該程序的做用域中。
angularjs找到ng-bind或者{{key}} 指令,它將數據渲染到該元素內。
angularjs遍歷其它指令,完畢後,就可使用應用程序。

ng-init

表示初始化應用程序中的變量,多個變量用; 注意定義多個變量不能用逗號,只能用分號;

<div ng-init="msg='hello wrold'; info='您輸入的信息爲:'" ng-controller="msg">
    <input type="text" name="" id="" value="" ng-model="msg" />
    <span ng-bind="msg"></span>
    <span>{{ info }}</span>
    <span>{{ msg }}</span>
</div>

module

經過angular.module方法
該方法有兩個參數
參數1,表示程序的名稱。
參數2,表示依賴服務(依賴集合)
依賴就是達到某個目的的必要條件(不可或缺)。

var app = angular.module('app', []);

controller控制器

定義控制器
App的controller方法:
兩個參數
第一個參數表示控制器的名稱
第二參數表示控制器的構造函數
參數是你須要的數據,須要什麼能夠傳遞什麼,這樣在構造函數中就可使用它,若是沒有傳遞就沒法使用
ng-controller 控制應用程序的,後期對某一視圖動態改變的做用

定義控制器
app.controller();
參數1:控制器名稱
參數2:控制器的回調函數(構造函數)
回調函數的參數是所須要的數據,須要什麼能夠傳遞什麼,這樣在回調函數中就可使用它,若是沒有傳遞就沒法使用

angular參數注入:想用什麼東西就在參數中注入。

  • 不要再控制器中操做 DOM。 經過指令完成。

  • 經過控制器完成的功能命名控制器,並以字符串Ctrl結尾,例如:(HomePageCtrl)

  • 控制器不該該全局中定義


  • 儘量精簡控制器,將通用函數抽線爲獨立的服務

  • 經過方法引用進行跨控制器通信(一般是子控制器與父控制器通信) 或者 $emit,$broaadcast 以及 $on 方法。發送或廣播的消息應該限定在最小的做用域。

  • 置頂一個經過 $emit,$boradcast 發送的消息列表而且窒息的管理以防止命名衝突

  • 在須要格式化數據時,將格式化邏輯封裝成 過濾器

<div ng-controller="msg"></div>

// 控制器
app.controller('msg', function ( $scope ) {
    
    console.log( this );
    console.log( arguments );
    
});

控制器$scope

$scope: 用來實現數據與視圖的鏈接,在$scope上定義的數據,能夠用視圖在上,那麼視圖上綁定的數據能夠在$scope上也能獲取到

$scope 是經過原型式繼承實現, 子做用域會繼承父做用域中的變量,可是能夠爲子做用域添加變量還重寫符做用域中的變量。

scope特色

  • $scope 是一個 POJO 簡單的Java對象

  • $scope 提供了一些工具方法$watch()/$apply();

  • $scope 表達式執行環境,或者說做用域

  • $scope 是一個樹型結構,與DOM標籤平行

  • 每個angularjs應用都有一個跟做用域$rootScope,位於ng-app上

  • $scope 能夠傳播事件,相似DOM事件,能夠向上下能夠向下

  • $scope 不只是MVC 的基礎,也是後買呢實現雙向綁定的基礎,應用開始先找rootScope,而後把下級scope附加到rootScope上從而造成樹型結構.

clipboard.png

scope生命週期

建立(creationd)

在建立控制器或指令時,angularjs會用$onjector建立一個新的做用域,並在這個新建的控制器或指令時把做用域傳進去

連接

scope對象會附加或連接到視圖。這些做用域將會註冊到 angular上下文中發生變化時須要運行的函數
$watch -> 註冊監控(Watcher registration) 變化時執行 回調函數

更新

事件循環執行時,頂級的$rootScoep和每一個子做用域都執行本身的髒值檢查。某個監控函數監控變化,檢測到變化後,$scope會觸發指定的回調函數。

銷燬

當scope在視圖中再也不須要時,會清晰和銷燬本身。
$scope.$destory();

events

ng-eventsName
例如:ng-click
若是想在回調函數中傳遞參數,在圓括號裏面直接添加

執行的做用域是$scope,當前的做用域
參數經過元素調用時傳遞的參數一致,最後一個參數爲事件對象

<button ng-click="clickBtn('info',$event)" ng-bind="red"></button>

// 事件
$scope.clickBtn = function ( msg, ev ) {
    
}

顯隱

ng-show 表示顯示元素指令
ng-show 顯示元素:true顯示,false隱藏
ng-hide 隱藏元素:true隱藏,false顯示

<span ng-show="isShow">1</span>
<span ng-hide="isShow">2</span>

表達式

插值和數據的過程當中能夠應用表達式
的綁定過程咱們能夠應用表達式
在表達式中不只僅能夠用運算符,還能夠應用js提供的方法

<div>{{'面積是:' + width * height}}</div>

<div>{{ msg.toUpperCase() }}</div>

過濾器

用來對綁定數據顯示時候處理
{{key | filter}}

內置過濾器

currency
格式化數字爲貨幣格式

<div>{{msg | json}}</div>
<div>{{ msg | currency }}</div>

filter
過濾數組項

<div ng-controller="filters">
    <div>{{ color | filter : 'n' }}</div>
    <div>{{ color | filter : filterChar }}</div>
    <div>{{ color | filter : filterFirstStr }}</div>
</div>

<script type="text/javascript">
    
    // app 
    var app = angular.module('appBody', []);
    
    // controller 
    app.controller('filters', function ( $scope ) {
        
        $scope.color = ['tan', 'khaki', 'Pink', 'cyan'];
        
        // a 過濾出來
        $scope.filterChar = 'a';
        
        $scope.filterFirstStr = function ( val ) {
            
            // 匹配首字母大寫
            return val[0] === val[0].toUpperCase();
            
        }
        
    });
    
    
</script>

date
日期過濾器,格式化日期

<div ng-controller="dates">
    <span>{{ iDate | date : 'yyyy' + '年'}}</span>
    <span>{{ iDate | date : 'MM' + '月' }}</span>
    <span>{{ iDate | date : 'dd' + '日' }}</span>
    <span>{{ iDate | date : 'HH' + ':' + 'mm' }}</span>
    <p>{{ iDate | date : 'yyyy年 MM月dd日 HH:mm' }}</p>
</div>

// app 
var app = angular.module('appBody', []);

// controller 
app.controller('filters', function ( $scope ) {
    
    $scope.color = ['tan', 'khaki', 'Pink', 'cyan'];
    
    // a 過濾出來
    $scope.filterChar = 'a';
    
    $scope.filterFirstStr = function ( val ) {
        
        // 匹配首字母大寫
        return val[0] === val[0].toUpperCase();
        
    }
    
});

limitTo
截取過濾器
參數表示截取的長度
這個過濾器不只僅能夠截取字符串,還能夠截取數組

<div>{{ color | limitTo : 2 }}</div>

<div>{{ msg | limitTo : 3 }}</div>

字符串大小寫
uppercase 將字符串轉化成大寫
lowercase 將字符串轉化成小寫
這個過濾器痛對數據直接調用字符串方法toUpperCase和toLowerCase效果是同樣的
可是angular建議使用過濾器
過濾器能夠被複用
不建議在表達式中使用方法(除特殊狀況)

<div>{{ msg | uppercase }}</div>
<div>{{ msg | lowercase }}</div>
<div>{{ msg.toLowerCase() }}</div>

number過濾器
是一種數字類型數據過濾器
參數表示截取小數位置
該過濾器是將數字以每三爲分割渲染的
不傳遞參數默認保留三維,最後一位四捨五入

<div>{{ num | number }}</div>
<div>{{ num | number : 4 }}</div>

orderBy
對數組進行排序的過濾器
參數1,數組中每一個成員排序的索引屬性名稱
參數2,正序仍是倒序 (true反序)

<div>{{ color | orderBy : '' : true }}</div>
<div>{{ color | orderBy }}</div>

自定義過濾器

定義
經過app提供的filter方法來定義過濾器 app.filter();接受兩個參數
參數1,過濾器的名稱
參數2,過濾器的回調函數(構造函數)
回調函數必須返回一個函數,這個函數在每次數據更新時候執行。
回調函數只執行一次
返回的函數,能夠接受過濾器使用時傳遞的參數,可是第一個參數永遠是綁定的數據,後的參數纔是傳遞的參數,參數的順序痛使用時傳遞參數的順序一致。

調用
使用方式同內置過濾器同樣,在管道符號後面添加過濾器的名稱,經過添加參數

  • 使用小駝峯命名

  • 儘量使過濾器精簡。 過濾器在 $digest loop 中頻繁被調用,過於複雜的運算使得整個應用執行緩慢。

  • 在過濾器中只作一件事. 更加複雜的操做能夠用pipe來實現.

    <!--自定義過濾器-->
    <input type="text" ng-model="msg" />
    <div>{{ msg | CaseChar }}</div>
    <div>{{ msg | CaseChar : true }}</div>

app.filter('CaseChar', function () {
    
    return function ( val, FirstToUpper ) {
    
        if ( val ) {
            
            // FirstToUpper 參數 表示第一個字母大寫
            if ( FirstToUpper ) {
                
                // 第一個字母 大寫
                val = val.replace(/^[a-z]/, function ( match, $1 ) {
                    
                    return match.toUpperCase();
                    
                });
                
            }
            
            // 存在輸入的val 值   轉駝峯
            return val.replace(/_([\w])/g, function ( match, $1 ) {
                
                return $1.toUpperCase();
                
            });
            
        } 
        
        return '';
        
    }
    
});

表單驗證

當對錶單元素form添加name屬性時候,angular會自動將該屬性的值添加到做用域中,而且該屬性具備表單驗證的屬性. 具備FormContorller對象

$dirty 表單是否被用戶輸入過,輸入過,值爲true,沒有輸入過值爲false
$pristine 表單是否被用戶輸入過,輸入過,值爲false,沒有輸入過值爲true
$valid 輸入的值是否合法,合法值爲true,不合法爲false
$invalid 輸入的值是否合法,合法值爲false,不合法爲true

$valid 屬性值爲true時,全部表單元素必須$valid都是true
$invalid 屬性爲true時,只要有一個表單元素$invalid之爲true
$dirty 屬性爲true時,只要有一個表單元素被修改過,$dirty值爲true
$pristine 屬性爲true時,全部的元素未被修改過,那麼$pristine值爲true

<form name="appForm">
    
    <label for="">用戶名:</label>
    <input type="text" name="username" ng-model="uname" ng-maxlength="5" id="" value="" />
    <span ng-show="appForm.username.$invalid">輸入的長度大於5</span>
    
</form>

<form name="appForm">
    
<!-- 兼容 HTML5 表單元素 -->
<label for="">郵箱:</label>
<input type="email" name="emial" ng-model="emailModel" id="" value="" />
<span ng-show="appForm.emial.$invalid">輸入內容必須是emial</span>
    
</form>

<form name="appForm">
    
<!--使用 ng-pattern 匹配正則-->
<input type="text" name="txt" ng-model="passModel" ng-pattern="/^\d{4,6}$/" id="" value="" />
<span ng-show="appForm.txt.$invalid">輸入的內容必須是4-6位數字</span>
    
</form>

run-$rootScope

獲取app並執行(程序入口指令會提供一個run方法),一般會在該方法中訪問根做用域,該方法接收一個函數做爲參數,
函數中的this指向window,所以能夠訪問到全局做用域下的變量。
arugments默認沒有值,須要什麼值,須要經過參數注入來供函數內使用。
做用:處理的是根做用域,所以一般要將$rootScope傳遞進來.

app.run(function ( $rootScope ) {
});

controller與做用域

var app = angular.module('main', []);

app.controller('parentCtrl', function ( $scope ) {
    
    $scope.clickParent = function () {
        
        $scope.msg = 'parentScope';
        
        
    }
    
}).controller('childCtrl', function ( $scope ) {
    
    $scope.clickChild = function () {
        
        $scope.msg = 'childScope';
        
    }
    
});

// rootScope
app.run(function ( $rootScope ) {
    
    $rootScope.msg = 'rootScope';
    
})

console.log( app );

ng指令

ng-disabled
表單是否能夠操做

<input type="text" ng-disabled="isable" name=""  />

ng-readonly
表單是不是隻讀

<input type="text" ng-readonly="isable" name="" id="" value="" />

ng-checked
選擇框是否被選中
值爲true:選中
值爲false:未選擇

<input type="checkbox" ng-checked="isabel" name="" id="" value="" />

ng-change
監聽輸入表單內容的改變,當表單內容改變的時候就會觸發.
改變的時候,須要知道數據是否更改,須要加上ng-model

<input type="text" ng-model="msg" ng-change="change()" name=""  />

app.controller('inp', function ( $scope ) {
    
    $scope.change = function () {
        
        alert($scope.msg);
        
    }
    
});

ng-submit
對form表單元素綁定submit事件,當點擊表單中submit元素時候,會觸發該事件
ng-submit須要搭配標籤form使用

<form name="forms" ng-submit="submit()">
    
    <input type="text" name="" ng-model="msg" id="" value="" />
    
    <input type="submit" value="提交"/>
</form>

ng-src
瀏覽器打開頁面,瀏覽器不認識ng-src屬性,所就不會發請求,那麼當ng-src綁定的數據imgSrc有數據的時候,angular會把這個數據賦值給src屬性,讓img標籤發送一個請求

<img ng-src="{{imgSrc}}" />

ng-href
當瀏覽器打開頁面的時候,元素不具備href屬性,就不具備連接行爲(爲#號卻可以點擊),ng-src對這一現象作了優化,當ng-href綁定的數據加載成功後,將這一屬性值,賦值給a標籤的href屬性,讓a標籤具備鏈接的行爲。

<a ng-href="{{Url}}">跳轉</a>

ng-class
是用來動態建立類的一個指令,它的只是一個對象,對象中的舒心表明類的名稱,屬性值只能是一個Boolean
true,會將該類名添加到元素的class屬性中。
false,會將該該類名從該元素的class屬性中刪除。

<div ng-class="{red: ngClassInfo>4, green: ngClassInfo <=4 }">{{ ngClassInfo }}</div>

ng-style
用來動態建立樣式,它的值是一個對象,對象中的屬性表示css屬性,值爲css屬性值。

<div ng-style="{background: 'tan', width: '100px', height: '100px'}"></div>

ng-if
判斷指令.
angular中沒有ng-else指令,能夠經過ng-if模擬

<div ng-if="isable">111111111111</div>
<div ng-if="!isable">222222222222</div>

ng-switch
分支判斷
當元素這是了ng-switch,元素是一個ie分支判斷的模板,全部分支都要包含在該元素內。
經過on指令來設置判斷條件,ng-switach和on配合使用
ng-switch-when="key":表示判斷某一條件,當on的綁定的數據值爲該分支對應的值的時候,執行。

<!--須要將分支判斷的元素放入 ng-switch 容器中-->            
<div ng-switch="" on="switchInfo">
    
    <div ng-switch-default="">默認</div>
    <div ng-switch-when="first">1111</div>
    <div ng-switch-when="second">2222</div>
    
</div>

ng-repeat
循環渲染模板
語法: ng-repeate="item in list";
內置變量
$index 循環的索引值,從0開始計數
$first 第一次循環是true,其它次循環是false
$last 最後一次循環是true,其它此循環是false
$middel 除去第一次和最後一次值是true
$even 偶數次循環是true,奇數次循環是false
$odd 奇數次循環是true,偶數次循環是false

<ul>
    <li ng-repeat="item in colors" ng-class="{red: $odd}">{{ item }} --- {{'索引值:'+$index}} --- {{ $middle }}</li>
</ul>

ng-include
模板定義在單獨文件中,經過ng-include引入進來.
ng-include="url" 注意url是字符串

<div ng-controller="aMsg">
    
    <div ng-include="'a.html'"></div>
        
</div>

// 數據傳輸
var aMsgApp = app.controller('aMsg', function ( $scope ) {
    
    $scope.msg = '載入成功';
    
});
  • 使用 ng-bind 或者 ng-cloak 而 不是使用 {{}} 插值方式,防止頁面渲染閃爍

  • 避免在插值中使用複雜代碼

  • 須要動態設置 <img> 的 src 時使用 ng-src 而不使用 src中嵌套 {{}}

  • 須要動態設置 <a> 的 href 時使用 ng-href 而不是用 href 中嵌套 {{}}

  • 經過對象參數和scope變量做爲值來使用 ng-style 指令, 而 不是使用 scope 變量做爲字符串經過 {{}} 用於 style 屬性。

自定義指令

directive();

參數1: 指令的名稱
參數2: 構造函數,自定義指令式,只執行一次,將一些複雜業務邏輯放在該函數中,最後改函數返回是一個對象(用來描述指令)

規則:

  • 使用小駝峯命名。

  • 在link function 中使用 $scope 。 在compile中, 定義參數的post/pre link functions 將在函數執行時被傳遞,沒法經過依賴注入改變它們。

  • 指令添加自定義前綴避免與第三方指令衝突

  • 可複用組件建立獨立做用域

  • 使用 scope.$on('$destroy', fn) 來清除. 這點在使用第三方指令的時候特別有用.

返回對象

restrict: 自定義指令的類型
E,該指令是一個自定義元素(element)
A,該指令在元素時屬性上(attributes)
C,該指令在元素的類上(class)
M,註釋指令(comment)

template: 傳遞的是模板字符串

templateUrl: 模板文件的路徑

replace: false
是否替換原有的元素,true會替換掉原有的元素,false不會替換掉元素。
當設置true時,會對controller中使用的參數$element 和 $attrs 有影響

controller
用來定義自定義指令的做用域。
this 指向的controller{}空對象
arguments默認狀況下是一個空數組,須要參數注入。
$scope 該指令的做用域
$element 該指令的元素
$attrs 該指令的元素的屬性

// directive() 自定義指令
app.directive('curtoms' , function () {
    
    console.log(111);
    
    return {
        
        // 指令類型
        restrict: 'EAC',
        
        // 模板字符串
//                    template: '<h1>自定義指令</h1>',
        
        // 模板文件獲取 url
        templateUrl: 'a.html',
        
        // replace表示是否替換原來的元素,true是替換,false不替換
//                    replace: false,
        replace: true,
        
        controller: function ( $scope, $element, $attrs ) {
            
            // this 指向 controller{} 空對象
            
            console.log( $scope, $element, $attrs );
            
        }
        
    }
    
});

scope
隔離自定義的做用域的屬性,經過對其社會字一個對象來隔離指令的做用域。
若是值是true或者false,指令的做用域就會忽略自身做用域,而去尋找父級做用域中的變量。
若是值是空對象{} ,做用域會指向該空對象

directive返回對象中的scope和controller
自定義指令中,scope屬性對controller的影響:
若是scope的值是true,在controller中,定義與父做用域中相同變量時,自定義指令中的變量不會受到反作用於中的變量的影響。
若是scope是一個false,在controller中,定義與父做用域相同變量時,該變量與父做用域中的變量同步(同時修改,數據雙向綁定)
若是scope是一個對象,在controller中,定義與父做用域相同的變量時,自定義指令中的變量不會收到父做用域的變量影響。

app.directive('myCutom', function () {
    
    return {
        
        restrict: 'E',
        
        template: '<h1>{{ msg }} -- {{ title }}</h1>',
        
        // scope: {},
        // scope: true,
            scope: false
        
        controller: function ( $scope, $element, $attrs ) {
            
            $scope.title = 'aaaa';
            
            $scope.msg = 'xixixi';
            
        }
        
    }
    
});

@修飾符
能夠屏蔽模板中變量去controller做用域中尋找值的過程,而是讓其去該自定義指令所在元素的屬性中尋找數據變量. 忽略自定義指令的scope。
@修飾符會去自定義指令中所在元素的屬性去尋找。
屬性值是插值傳入,做爲普通屬性處理。

<my-custom my-title="{{title}}"></my-custom>

app.directive('myCutom', function () {
    
    return {
        
        restrict: 'E',
        
        template: '<h1>{{ msg }} -- {{ title }}</h1>',

        scope: {
        // 告知 自定義指令 不須要從 本身的做用域中尋找 變量
            title: '@myTitle'
        },

        controller: function ( $scope, $element, $attrs ) {
            
            $scope.title = 'aaaa';
            
            $scope.msg = 'xixixi';
            
        }
        
    }
    
});

=修飾符
經過在scope屬性中定義含有=修飾符的變量時,能夠取得父做用域中的變量,經過屬性映射.

做用:自定義指令做用域中變量與父做用域的雙向綁定過程.
注意:自定義元素中的屬性值是一個父做用域中的一個變量,在自定義指令中看成一個變量來處理。

template,中的數據和 父級的做用域$scope,數據綁定

tempalte: '<h1>{{title}}</h1>',

app.controller('main', function ( $scope ) {
    $scope.title = '';
});

link

操做自定義指令的DOM

link的函數
this指向window
arguments:
1 scope, 指令做用域
2 jqlite 獲取自定義元素
3 attrs 自定義指令元素上的屬性

// 操做自定義指令元素
// @param {Object} scope  子做用域
// @param {Object} jqlite JQ對象
// @param {Object} attrs 自定義上的屬性
link: function ( scope, jqlite, attrs ) {
    
    // this -> window
    var el = jqlite.children('h1').attr('nodeValue', 1);
    
    // 使用 data 自定義屬性  ,會自動省略  data-
    
    for ( var i=0; i<attrs.repeate; i++ ) {
        
        jqlite.append( el.clone() );
        
    }
    
}

complie

this指向的是指令描述對象.
參數1: jqlite 獲取的自定義元素
參數2: attrs 自定義指令所在元素的屬性
返回一個函數, 指向 link 函數
在返回函數中,能夠操做自定義指令所在元素.

<div ng-controller="main">
    
    <my-directive data-color="pink">
        <h1>嘻嘻哈哈</h1>
    </my-directive>
    
</div>

<script type="text/javascript">
    
    // 建立 app
    var app = angular.module('app', []);
    
    // 建立控制器
    app.controller('main', function ( $scope ) {});
    
    // 自定義指令
    app.directive('myDirective', function () {
        
        return {
            
            restrict: 'E',

            // 自定義指令的編譯方法
            // @param {Object} jqlite  獲取自定義指令元素
            // @param {Object} attrs   自定義指令所在元素上的樣式
            // @return {Function} cb   指代 link 
            compile: function ( jqlite, attrs ) {
                
                // this -> compile 對象 
                
                return function ( scope, jqlite, attrs ) {
                    
                    // this -> window
                    var color = attrs.color;
                    
                    jqlite.css('color', color);
                    
                }
                
            }
            
        }
        
    });
    
</script>

transclude

它告訴自定義指令,要將自定義元素中未知的元素內容插入到已知模板具備ng-transclude指令所在的元素中(添加自定義指令元素中的未知元素)
未知元素:自定義標籤中的元素.

告知自定義指令,要將自定義中未知的元素內容插入到已知模板。
條件: 模板標籤上具備ng-transclude指令
須要設置 transclude: true.

現象:模板標籤會包裹自定義標籤內的內容.

app.directive('myDirective', function () {
    
    return {
        
        restrict: 'E',
        
        template: '<div ng-transclude></div>',
        
        transclude: true    
        
    }
    
});

require

自定義指令引用其它指令,做爲link()方法的第四個參數.
例如,將ngModel引入到自定義指令中. 在link方法中能夠訪問到ngModel中的屬性值

require: 'ngModel'

// 自定義指令
app.directive('myDirective', function () {
    
    // 返回一個描述指令對象
    return {
        
        restrict: 'A',
        
        // 引入其它指令
        require: 'ngModel',
        
        link: function ( scope, jqlite, attrs, ngModel ) {
            
            // $watch 檢測某個值 發生改變,觸發某個函數
            // 當 ngModel 值發生改變, 觸發函數
            scope.$watch(attrs.ngModel, function () {
                
                console.log(ngModel.$viewValue);
                
            });
            
        }
        
    }
    
});

服務

對一些方法的封裝,複用方法更爲簡便。例如:消息系統,做爲消息服務.
使用服務,利用參數注入便可。

  • 大駝峯和小駝峯均可

  • 將業務邏輯封裝成服務

  • 將業務邏輯封裝成 service 而非 factory

  • 使用 $cacheFactory 進行繪畫級別的緩存。 應用於緩存請求或複雜運算的結果。

內置服務

$timeout
對setTimeout()的封裝

app.controller('main', function ($scope, $timeout) {

    $timeout(function () {

        console.log(this);
        console.log(arguments);
        
    }, 2000);

});

$interval
對setInter();的封裝

app.controller('main', function ($scope, $interval) {
    // 定義一個時間
    $scope.date = new Date();

    $interval(function () {
        // 從新定義日期
        $scope.date = new Date();
    }, 1000);

});

$http
異步請求

配置參數:
method: 請求方式 "GET","POSt"
url: 請求的地址
$http 方法執行完後鏈式調用success(),請求成功的回調函數

POST請求:
經過設置data屬性添加POST請求發送數據
params屬性添加請求的參數數據

// $http 服務
$http({
    method: 'GET',
    url: 'data/service.json'
}).success(function ( res ) {  
    
    if ( res.errno === 0 ) {
        
        $scope.msg = res.msg;
    
        console.log(res);
        
    }
    
});

$http({
    method: 'POST',
    url: 'demo.json',
    // 該屬性會將鍵值對轉化成url上參數
    params: {
        id: 11
    },
    // post請求 添加請求數據
    data: {
        username: 'aa'
    }
});

$http.get,$http.post
$http服務中的get請求和post請求簡寫方式
params 配置請求參數

// get 請求
$http.get('data/service.json', {
    params: {
        id: 1
    }
})
// 請求成功
.success(function ( res ) {
    
    console.log( res );
    
});

// post 請求
// 參數1:url ,參數2:請求攜帶的數據
$http.post('data/service.json', {
    id: 1
})
// 請求成功
.success(function ( res ) {
    
    console.log(res);
    
});

promise對象
允諾對象,在內部是一個異步操做,當操做完成時,這個對象會實現它的允諾.
特色: 能夠無限添加允諾。 必定在某些操做完成時纔出發。
規範中允諾對象使用 then方法.

自定服務

須要各類服務以支持各類功能,也能夠手動開啓或關閉某些服務以達到相應的功能.

factory()
工廠模式定義自定義服務
參數1:服務名稱
參數2:服務工廠方法
返回值:服務對象,這個對象提供其它控制器使用

var app = angular.module('app', []);

// 其它控制器使用服務
app.controller('facotryCtrl', function ( $scope, news ) {
    
    $scope.msg = news.data;
    
});

// factory 定義 服務
app.factory('news', function () {
    
    return {
        data: '嘻嘻哈哈'
    }
    
});

service

面向對象建立服務
參數1:服務名稱
參數2:服務的構造函數(構造函數中須要使用this來暴露接口)

// 使用 service 自定義服務
app.service('data', function () {
    
    this.title = '嘻嘻哈哈';
    
});

路由

使用組件配合使用:
angular-route.js
angular-ui-router.js
用來尋找頁面,一般經過配置一些路由來映射一些頁面

路由:就是URL到函數的映射

ngRoute

須要在程序入口處引入,添加到依賴集合中

angualr.module('app', ['ngRoute']);

ng-view

動態渲染的視圖,視圖如何渲染根據路由決定

<div ng-view></div>

渲染視圖須要在頁面初始化以前知道路由配置.
使用congfig();

congfig();
在應用程序執行以前執行一個配置方法,在頁面還未被渲染,能夠將路由邏輯放入該方法中。
回調函數:
this -> window
默認參數是空的,須要將服務注入

// 配置
app.config(function ( $routeProvider ) {

$routeProvider.when('/', {
    
    // 模板
// template: '<div>嘻嘻哈哈</div>',
    templateUrl: 'a.html',
    
    // 控制器
    controller: function ( $scope ) {
        
        console.log( $scope );
        
        $scope.style = {
            color: 'deeppink'
        }
        
    }
    
});

$routeProvider
路由服務:
路由供給服務,提供一個when方法,供使用配置路由.

controller
在路由對象中,能夠經過controller屬性,爲路由對象添加控制器,建立一個做用域,讓模板可使用做用域中的變量。

template
配置模板字符串

templateUrl
配置外部模板
會發送異步請求

otherwise
重定義路由
配置兩個路由以上,otherwise 纔會有效果.
配置參數爲 redirectTo 來重定向到不一樣路由,值是定義過路徑.

// app
var app = angular.module('app', ['ngRoute']);

// controller
app.controller('routerCtrl', function ( $scope ) {
    
    $scope.shop = 'shopPage1';
    
});

// config
app.config(function ( $routeProvider ) {
    
    // 配置首頁 路由  
    $routeProvider.when('/', {
        
        template: '<h1>{{ index }}</h1>',
        
        controller: function ( $scope ) {
            
            $scope.index = 'indexPage';
            
        }
        
    })
    
    // 配置  shop 頁面 路由
    .when('/shop', {
        
        template: '<h1>{{ shop }}</h1>',
        
        controller: function ( $scope ) {
            
                //    $scope.shop = 'shopPage';
            
        }
        
    })
    
    // 其它路由 重定義 到  / 目錄中
    .otherwise({
        redirectTo: '/'
    });
    
});

路由參數

路由路徑配置參數(參數名前須要加:冒號)
將獲取路由參數服務注入控制器中($routeParams注入控制器中).

app.config(function ( $routeProvider ) {
    
    // 配置參數
    $routeProvider.when('/shop/:pageNum/:type', {
        
        template: '<h1>{{ shop }}</h1>',
        
        // 參數注入
        controller: function ( $scope, $routeParams ) {
            
            $scope.shop = 'shopPage';
            
            console.log( $routeParams );
            
        }
        
    });

});

路由時間
路由時間一般定義須要監聽該事件的控制器中,在全局做用域下監聽,經過對做用域$on()方法監聽路由事件。
例如:$routeChangeSuccess
監聽路由改變成功
參數1: 表示事件對象
參數2:表示當前路由對象
參數3:表示前一個路由(若是當前沒有前一個路由對象,所以參數會是undefined)

app.run(function ( $rootScope ) {
    
    $rootScope.$on('$routeChangeSuccess', function ( ev, routeObj, preRouteObj ) {
        
        
    });
    
});

$location
管理地址欄狀態信息,包括query,path
path(): 改變路由中的path.
讀:$location.path();
設:$loction.path(arg);

app.run(function ( $rootScope, $location ) {
    
    $rootScope.$on('$routeChangeSuccess', function ( ev, routeObj, preRouteObj ) {
        
        // var q = $location.path(); // 讀
        
        $location.path('/xixi'); // 設置  
        
    });
    
});

ui-router

ngRoute: 每一個頁面對應一個地址(path), 須要渲染那個頁面,就須要配置路由.
uiRouter: 引入state(狀態)概念,若是哪一個頁面若是顯示,渲染出對應的頁面,渲染以後會有一種狀態,能夠將該狀態記錄,配置路由

ui-view

在ui-router 中使用的指令ui

<div ui-view=""></div>

$stateProvider
參數注入到config()來定義狀態

app.config(function ( $stateProvider ) {});

state();
定義狀態
參數1:狀態名稱
參數2:配置參數
url: 狀態頁面的地址
tempate: 狀態對應頁面的模板
controller 定義狀態對應頁面的做用域

// 參數注入 ui.router
var app = angular.module('app', ['ui.router']);

// 配置路由
app.config(function ( $stateProvider ) {

// $stateProvider 定義狀態
console.log( $stateProvider );

$stateProvider.state('home', {
    
    // 配置 #/
    url: '/',
    
    template: '<h1>{{ indexPage }}</h1>',
    
    controller: function ( $scope ) {
            
        $scope.indexPage = 'indexPage';
        
        console.log( this,arguments );
        
    }
    
})

.state('shop', {
    
    url: '/shop',
    
    template: '<h1>{{ shopPage }}</h1>',
    
    controller: function ( $scope ) {
        
        $scope.shopPage = 'shopPage';
        
        console.log( this,arguments );
        
    }
    
})

});

uiRouter路由參數規則
路由規則:

  • 固定值:/key

  • 可捕獲的參數: /:key

  • 限制字段類型: /{key:type} type: int,string

  • 捕獲query: ?queryNum&queryNum2

$stateProvider.state('shop', {
    
    // url: '/shop/xixi/is/100?form=10&to=20'
    url: '/shop/:value/is/{pageNum:int}?form&to',
    
    template: '<h1>{{ shopPage }}</h1>',
    
    controller: function ( $scope, $stateParams ) {
        
        console.log( $stateParams );
        
        $scope.shopPage = 'shopPage';
        
    }
    
})

$urlRouterProvider
when(); 將參數1的路由路徑重定向到參數2路由路徑
otherwise(); 匹配不存在的路由,跳轉到定義過的路由.

// 配置 不存在路由    
$urlRouterProvider.when('', '/').otherwise('/error');

views 多視圖
ui-router 能夠渲染頁面中的多個視圖,經過爲頁面中ui-view指令添加名稱,多個視圖渲染須要在config() 配置。

<div>
    <div class="left" ui-view="leftView"></div>
    <div class="content" ui-view="contentView"></div>
    <div class="right" ui-view="rightView"></div>
</div>

app.config(function ( $stateProvider, $urlRouterProvider ) {

$stateProvider.state('home', {
    
    url: '/',
    
    views: {
        
        leftView: {
            
            template: '<h1>leftView</h1>'
            
        },
        
        rightView: {
            
            template: '<h1>rightView</h1>'
            
        },
        
        contentView: {
            
            template: '<h1>contentView {{ msg }}</h1>',
            
            controller: function ( $scope ) {
                
                $scope.msg = '中間模塊'
                
            }
            
        }
        
    }
    
});

view 嵌套
在 ui-reouter 中視圖是能夠嵌套。
在state() 定義狀態名稱的時候添加命名空間。
路由須要有順序,定義在父路由的後邊。
注意:父視圖須要添加動態視圖ui-view
多視圖不能與嵌套視圖同時使用
匹配主頁,定義路徑不須要添加 '/shop', 直接 'shop';便可.

app.config(function ( $stateProvider, $urlRouterProvider ) {
    
    $stateProvider.state('home', {
        
        url: '/',
        
        template: '<div>index<div ui-view></div></div>'
        
    })
    .state('home.shop', {
        
        url: 'shop',
        
        template: '<h1>shopPage</h1>'
        
    });
    
    $urlRouterProvider.when('','/');
    
});

路由事件
添加在全局做用域$rootScope 下檢測路徑變化
事件名以state開頭
參數1: 事件對象
參數2: 當前路由對象
參數3: 當前路由參數對象
參數4: 前一個路由對象
參數5: 前一個路由參數對象

app.run(function ( $rootScope ) {
    
    $rootScope.$on('$stateChangeSuccess', function ( ev, routeObj, routeParamsObj, preRouteObj, preRouteParamsObj ) {
        
        console.log( this,arguments );
        
    })
    
});
相關文章
相關標籤/搜索