看書總結之AngularJS權威教程


title: 看書總結之AngularJS權威教程

第一章 初始AngularJS

1.瀏覽器是如何獲取網頁的

當你打開一個瀏覽器,并在地址欄輸入URL后,瀏覽器會詢問DNS服務器該URL對應的IP地址是什么。如果DNS知道IP是什么就會將其結果返回,否則它會將請求轉發(fā)給其他的DNS服務器,直到在某一臺DNS服務器上找到對應的IP地址記錄,在終端輸入下列指令,可以觀察DNS服務器的響應內容:

$ dig baidu.com

DNS服務器返回了你要訪問的計算機的IP地址后,它就會向這個IP地址對應的計算機請求你要訪問的頁面?,F(xiàn)在,計算機已經知道了在哪個IP地址可以訪問到http://wwwbaidu.com,它會向百度的服務器
請求顯示這個頁面所需的HTML。當遠程服務器把HTML文檔發(fā)送回來后,瀏覽器會對文檔進行渲染。渲染就是通過一系列操
作,使HTML頁面按照設計之初的既定方式顯示。

2.瀏覽器是什么

目前市場上有很多不同品牌的瀏覽器,常見的有Chrome、Safari、Firefox和IE。它們的核心
功能基本上都是相同的:獲取網頁,并將它顯示給用戶。
瀏覽器獲取頁面對應的HTML文本,將其解析為一個在瀏覽器內部使用的結構,對頁面的內
容進行布局,并在內容顯示到屏幕上之前加上樣式,所有這些工作都是在瀏覽器內部進行的。
作為Web開發(fā)人員,我們的工作是構造網頁的結構和內容,這樣瀏覽器才能將它們轉化成對
用戶來說比較美觀的形式。
使用AngularJS,不僅可以構建頁面的結構,而且可以構建用戶和Web應用之間的交互

3.Angular是什么

官方文檔:完全使用Javascript編寫的客戶端技術,同其他歷史悠久的WEB技術配合使用,使Web應用開發(fā)比以往更簡單、更快捷

AngularJS主要用于構建單頁面Web應用。它通過增加開發(fā)人員和常見Web應用開發(fā)任務之間
的抽象級別,使構建交互式的現(xiàn)代Web應用變得更加簡單

第二章 數據綁定和第一個AngularJS Web應用

1.AngularJS中的數據綁定

  • AngularJS采用了完全不同的解決方案。他創(chuàng)建實時模板來代替視圖,而不是將數據合并進模板之后更新DOM。任何一個獨立視圖組件中的值都是動態(tài)替換的

2.簡單的數據綁定

    function MyController($scope, $timeout) {
    var updateClock = function() {
     $scope.clock = new Date();
    $timeout(function() {
    updateClock();
    }, 1000);
    };
    updateClock();
    };

3.數據綁定的最佳實踐

由于JavaScript自身的特點,以及它在傳遞值和引用時的不同處理方式,通常認為,在視圖中
通過對象的屬性而非對象本身來進行引用綁定,是Angular中的最佳實踐

function MyController($scope) {
$scope.clock = {
now: new Date()
};
var updateClock = function() {
$scope.clock.now = new Date()
};
setInterval(function() {
$scope.$apply(updateClock);
}, 1000);
updateClock();
};

第三章 模塊

模塊能帶來的好處

  • 保持全局命名空間的清潔;
  • 編寫測試代碼更容易,并能保持其清潔,以便更容易找到互相隔離的功能;
  • 易于在不同應用間復用代碼;
  • 使應用能夠以任意順序加載代碼的各個部分。

angular.module()方法聲明模塊,這個方法接受兩個參數
一個是模塊名稱,另一個是依賴列表

angular.module("myApp", []); 相當于AngularJS模塊的setter方法,是用來定義模塊的;

angular.module("myApp") 相當于AngularJS模塊中的getter方法,用來獲取對模塊的引用。

name(字符串)
name模塊的名稱,字符串變量
requires(字符串數組)
requires包含了一個字符串變量組成的列表,每個元素都是一個模塊名稱,本模塊依賴于這些模塊,依賴需要在本模塊加載之前由注入器進行預加載。

第四章 作用域

應用的作用域是和應用的數據模型相關聯(lián)的,同時作用域也是表達式執(zhí)行上下文。$scope對象時定義應用業(yè)務邏輯、控制器方法和視圖屬性的地方。
作用域提供了監(jiān)視數據模型變化的能力。它允許開發(fā)者使用其中的apply機制,將數據模型的變化在整個應用范圍內進行通知。我們在作用域的上下文中定義和執(zhí)行表達式,同時它也是將事件通知給另一個控制器和應用其他部分的中介。

1.視圖和$scope的世界

  • AngularJS啟動并生成視圖時,會將根ng-app元素同$rootscope進行綁定。$rootscope是所有對象的最上層。
  • $rootScope是AngularJS中最接近全局作用域的對象。在$rootScope上附加太多業(yè)務邏并不是好主意,這與污染JavaScript的全局作用域是一樣的。
  • $scope對象就是一個普通的JavaScript對象,我們可以在其上隨意修改或添加屬性。
  • $scope對象在AngularJS中充當數據模型,但與傳統(tǒng)的數據模型不一樣,$scope并不負責處理和操作數據,它只是視圖和HTML之間的橋梁,它是視圖和控制器之間的膠水
  • $scope的所有屬性,都可以自動被視圖訪問到

2.就是HTML而已

我們可以在AngularJS應用的模板中使用多種標記

  • 指令:將DOM元素增強為可復用的DOM組件的屬性或元素。
  • 值綁定:模板語法{{ }}可以將表達式綁定到視圖上。
  • 過濾器:可以在視圖中使用的函數,用來進行格式化。
  • 表單控件:用來檢驗用戶輸入的控件。

3.作用域的作用

  • 提供觀察者以監(jiān)視數據模型的變化;
  • 可以將數據模型的變化通知給整個應用,甚至是系統(tǒng)外的組件;
  • 可以進行嵌套,隔離業(yè)務功能和數據;
  • 給表達式提供運算時所需的執(zhí)行環(huán)境。

作用域包含了渲染視圖時所需要的功能和數據,它是所有視圖的唯一源頭??梢詫⒆饔糜蚶斫獬梢晥D模型。
下面看一個例子吧:

視圖中:
    <div ng-app="myApp">
    <h1>Hello {{ name }}</h1>
    </div>
    在$rootScope中設置了一個name變量并在視圖中引用了它:
    angular.module('myApp', [])
    .run(function($rootScope) {
    $rootScope.name = "World";
    });

我們可以不講變量設置在$rootscope上,而是用控制器顯式創(chuàng)建一個隔離的子$scope對象,把它設置到這個子對象上。
例子如下:

    <div ng-app="myApp">
    <div ng-controller="MyController">
    <h1>Hello {{ name }}</h1>
    </div>
    </div>
    
    angular.module("myApp", [])
    .controller('MyController',
    function($scope) {
    $scope.name = "Ari";
    });

ng-controller指令為這個DOM元素創(chuàng)建了一個新的$scope對象,并將它嵌套在$rootScope中

4.$scope的生命周期

  • 當Angular關心的事件發(fā)生在瀏覽器中時,比如用戶在通過ng-model屬性監(jiān)控的輸入字段中輸入,或者帶有ng-click屬性的按鈕被點擊時,Angular的事件循環(huán)都會啟動。這個事件將在Angular執(zhí)行上下文中處理。
  • 每當事件被處理時,$scope就會對定義的表達式求值。此時事件循環(huán)會啟動,并且Angular應用會監(jiān)控應用程序內的所有對象,臟值檢測循環(huán)也會運行。

$scope對象的生命周期處理有四個不同階段

1.創(chuàng)建
在創(chuàng)建控制器或指令時,AngularJS會用$injector創(chuàng)建一個新的作用域,并在這個新建的控制器或指令運行時將作用域傳遞進去

2.鏈接
當Angular開始運行時,所有的$scope對象都會附加或者鏈接到視圖中。所有創(chuàng)建$scope對象的函數也會將自身附加到視圖中。這些作用域將會注冊當Angular應用上下文中發(fā)生變化時需要運行的函數。
這些函數被稱為$watch函數,Angular通過這些函數獲知何時啟動事件循環(huán)

3.更新
當事件循環(huán)運行時,它通常執(zhí)行在頂層$scope對象上(被稱作$rootScope),每個子作用域都執(zhí)行自己的臟值檢測。每個監(jiān)控函數都會檢查變化。如果檢測到任意變化,$scope對象就會觸發(fā)指定的回調函數

4.銷毀
當一個$scope在視圖中不再需要時,這個作用域將會清理和銷毀自己
盡管永遠不會需要清理作用域(因為Angular會為你處理),但是知道是誰創(chuàng)建了這個作用域還是有用的,因為你可以使用這個$scope上叫做$destory()的方法來清理這個作用域

第五章 控制器

控制器在AngularJS中的作用是增強視圖

AngularJS中的控制器是一個函數,用來向視圖的作用域中添加額外的功能。我們用它來給作用域對象設置初始狀態(tài),并添加自定義行為。

當我們在頁面上創(chuàng)建一個新的控制器時,AngularJS會生成并傳遞一個新的$scope給這個控制器。可以在這個控制器里初始化$scope。由于AngularJS會負責處理控制器的實例化過程,我們只需編寫構造函數即可。

展示控制器初始化:

    function FirstController($scope) {
    $scope.message = "hello";
    }

在創(chuàng)建作用域時,我們最好不要再全局作用域中創(chuàng)建函數,因為會污染全局明明空間,合理的方式是創(chuàng)建一個模塊,然后在模塊中創(chuàng)建控制器

    var app = angular.module('app', []);
    app.controller('FirstController', function($scope) {
    $scope.message = "hello";
    });

只需創(chuàng)建控制器作用域中的函數,就能創(chuàng)建可以在視圖中使用的自定義操作,AngularJS允許我們在視圖中像調用普通數據一樣調用$scope上的函數。

控制器可以將與一個獨立視圖相關的業(yè)務邏輯封裝在一個獨立的容器中。盡可能地精簡控制器是很好的做法。作為AngularJS開發(fā)者,使用依賴注入來訪問服務可以實現(xiàn)這個目的

AngularJS同其他JavaScript框架最主要的一個區(qū)別就是,控制器并不適合用來執(zhí)行DOM操作、格式化或數據操作,以及除存儲數據模型之外的狀態(tài)維護操作。它只是視圖和$scope之間的橋梁。

AngularJS允許在$scope上設置包括對象在內的任何類型的數據,并且在視圖中還可以展示對象的屬性

在擁有ng-controller這個屬性的元素的任何子元素都可以訪問定義在controller里面的對象,因為它是定義在$scope上的

$scope對象用來從數據模型向視圖傳遞信息。同時,它也可以用來設置事
件監(jiān)聽器,同應用的其他部分進行交互,以及創(chuàng)建與應用相關的特定業(yè)務邏輯

    app.controller('MyController', function($scope) {
        $scope.person = {
        name: 'Ari Lerner'
        };
    });
    
    <div ng-app="myApp">
        <div ng-controller="MyController">
            <h1>{{ person }}</h1>
            and their name:
            <h2>{{ person.name }}</h2>
        </div>
    </div>

控制器的嵌套

AngularJS應用的任何一個部分,無論它渲染在哪個上下文中,都有父級作用域存在。對于ng-app所處的層級來講,它的父級作用域就是$rootScope

有一個例外:在指令內部創(chuàng)建的作用域被稱作孤立作用域。

除了孤立作用域外,所有的作用域都通過原型繼承而來,也就是說它們都可以訪問父級作用域

默認情況下,AngularJS在當前作用域中無法找到某個屬性時,便會在父級作用域中進行查找。如果AngularJS找不到對應的屬性,會順著父級作用域一直向上尋找,直到抵達$rootScope為止。如果在$rootScope中也找不到,程序會繼續(xù)運行,但視圖無法更新

看下例子再理解吧:

    app.controller('ParentController', function($scope) {
        $scope.person = {greeted: false};
    });
    app.controller('ChildController', function($scope) {
        $scope.sayHello = function() {
        $scope.person.name = 'Ari Lerner';
        };
    });

    <div ng-controller="ParentController">
        <div ng-controller="ChildController">
            <a ng-click="sayHello()">Say hello</a>
        </div>
        {{ person }}
    </div>

第六章 表達式

表達式和eval(javascript)非常相似,但是由于表達式由AngularJS來處理,它們有以下顯著不同的特性:

  • 所有的表達式都在其所屬的作用域內部執(zhí)行,并有訪問本地$scope的權限;
  • 如果表達式發(fā)生了TypeError和ReferenceError并不會拋出異常;
  • 不允許使用任何流程控制功能(條件控制,例如if/eles);
  • 可以接受過濾器和過濾器鏈。
    對表達式進行的任何操作,都會在其所屬的作用域內部執(zhí)行,因此可以在表達式內部調用那些限制在此作用域內的變量,并進行循環(huán)、函數調用、將變量應用到數學表達式中等操作。

解析AngularJS表達式

盡管AngularJS會在運行$digest循環(huán)的過程中自動解析表達式,但有時手動解析表達式也是非常有用的。

AngularJS通過$parse這個內部服務來進行表達式的運算,這個服務能夠訪問當前所處的作用域。這個過程允許我們訪問定義在$scope上的原始JavaScript數據和函數

將$parse服務注入到控制器中,然后調用它就可以實現(xiàn)手動解析表達式
下面舉個例子:

    <div ng-controller="MyController">
        <input ng-model="expr"
            type="text"
            placeholder="Enter an expression" />
        <h2>{{ parseValue }}</h2>
    </div>

我們可以在MyController中給expr這個表達式設置一個$watch并解析它

    angular.module("myApp", [])
    .controller('MyController',
    function($scope,$parse) {
    $scope.$watch('expr', function(newVal, oldVal, scope) {
        if (newVal !== oldVal) {
    // 用該表達式設置parseFun
        var parseFun = $parse(newVal);
    // 獲取經過解析后表達式的值
        $scope.parsedValue = parseFun(scope);
        }
        });
    });

2.插值字符串**(理解)

在AngularJS中,我們的確有手動運行模板編譯的能力。例如,插值允許基于作用域上的某個條件實時更新文本字符串。
要在字符串模板中做插值操作,需要在你的對象中注入$interpolate服務。

    我們將它注入到一個控制器中
    angular.module('myApp', [])
    .controller('MyController',
        function($scope, $interpolate) {
    // 我們同時擁有訪問$scope和$interpolate服務的權限
    });

$interpolate服務是一個可以接受三個參數的函數。

  • text(字符串)::一個包含字符插值標記的字符串(必須)
  • mustHaveExpression(布爾型):如果將這個參數設為true,當傳入的字符串中不含有表達式時會返回null
  • trustedContext(字符串):AngularJS會對已經進行過字符插值操作的字符串通過$sec.getTrusted()方法進行嚴格的上下文轉義
    $interpolate服務返回一個函數,用來在特定的上下文中運算表達式。
    <div ng-controller="MyController">
        <input ng-model="to"
            type="email"
            placeholder="Recipient" />
        <textarea ng-model="emailBody"></textarea>
        <pre>{{ previewText }}</pre>
    </div>

由于控制器內部設置了一個需要每次變化都重新進行字符插值的自定義輸入字段,因此需要設置一個$watch來監(jiān)聽數據的變化

    angular.module('myApp', [])
    .controller('MyController', function($scope, $interpolate) {
        // 設置監(jiān)聽
        $scope.$watch('emailBody', function(body) {
            if (body) {
                var template = $interpolate(body);
                $scope.previewText =
                    template({to: $scope.to});
            }
        };
    });

現(xiàn)在,在{{ previewText }}內部的文本中可以將{{ to }}當做一個變量來使用,并對文本的變化進行實時更新

用startSymbol()方法可以修改標識開始的符號。這個方法接受一個參數。

  • value(字符型):開始符號的值。

用endSymbol()方法可以修改標識結束的符號。這個方法也接受一個參數。

  • value(字符型): 結束符號的值。

如果要修改這兩個符號的設置,需要在創(chuàng)建新模塊時將$interpolateProvider注入進去

    //重新配置
    angular.module('emailParser', [])
    .config(['$interpolateProvider', function($interpolateProvider) {
    $interpolateProvider.startSymbol('__');
    $interpolateProvider.endSymbol('__');
    }])
    //定義一個服務
    .factory('EmailParser', ['$interpolate', function($interpolate) {
    // 處理解析的服務
    return {
    parse: function(text, context) {
    var template = $interpolate(text);
    return template(context);
    }
    };
    }]);

我們已經創(chuàng)建了一個模塊,可以將它注入到應用中,并在郵件正文中運行這個郵件解析器:

    //在應用中運用
    angular.module('myApp', ['emailParser'])
    .controller('MyController', ['$scope', 'EmailParser',
    function($scope, EmailParser) {
    // 設置監(jiān)聽
    $scope.$watch('emailBody', function(body) {
    if (body) {
    $scope.previewText = EmailParser.parse(body, {
    to: $scope.to
    });
    }
    });
    }]);


    <div id="emailEditor">
    <input ng-model="to"
    type="email"
    placeholder="Recipient" />
    <textarea ng-model="emailBody"></textarea>
    </div>
    <div id="emailPreview">
    <pre>__ previewText __</pre>
    </div>

第七章 過濾器

過濾器用來格式化需要展示給用戶的數據。
在HTML中的模板綁定符號{{}}內通過|符號來調用過濾器。

    {{ name | uppercase }}

在JavaScript代碼中可以通過$filter來調用過濾器。

    app.controller('DemoController', ['$scope', '$filter',
    function($scope, $filter) {
        $scope.name = $filter('lowercase')('Ari');
    }]);

以HTML的形式使用過濾器時,如果需要傳遞參數給過濾器,只要在過濾器名字后面加冒號即可。如果有多個參數,可以在每個參數后面都加入冒號

    {{ 123.456789 | number:2 }}

可以用|符號作為分割符來同時使用多個過濾器

AngularJS提供的內置過濾器

currency

currecy過濾器可以將一個數值格式化為貨幣格式。用{{ 123 | currency }}來將123轉化成貨幣格式

currecy過濾器允許我們自己設置貨幣符

date

date過濾器可以將日期格式化成需要的格式。AngularJS中內置了幾種日期格式,如果沒有指定使用任何格式,默認會采用mediumDate格式

    {{ today | date:'medium' }} <!-- Aug 09, 2013 12:09:02 PM -->
    
    {{ today | date:'short' }} <!-- 8/9/1312:09PM -->
    
    {{ today | date:'fullDate' }} <!-- Thursday, August 09, 2013 -->
    
    {{ today | date:'longDate' }} <!-- August 09, 2013 -->
    
    {{ today | date:'mediumDate' }}<!-- Aug 09, 2013 -->
    
    {{ today | date:'shortDate' }} <!-- 8/9/13 -->
    
    {{ today | date:'mediumTime' }}<!-- 12:09:02 PM -->
    
    {{ today | date:'shortTime' }} <!-- 12:09 PM -->

    ? 年份格式化
    四位年份:{{ today | date:'yyyy' }} <!-- 2013 -->
    兩位年份:{{ today | date:'yy' }} <!-- 13 -->
    一位年份:{{ today | date:'y' }} <!-- 2013 -->
    ? 月份格式化
    英文月份:{{ today | date:'MMMM' }} <!-- August -->
    英文月份簡寫:{{ today | date:'MMM' }} <!-- Aug -->
    數字月份:{{ today |date:'MM' }} <!-- 08 -->
    一年中的第幾個月份:{{ today |date:'M' }} <!-- 8 -->
    ? 日期格式化
    數字日期:{{ today|date:'dd' }} <!-- 09 -->
    一個月中的第幾天:{{ today | date:'d' }} <!-- 9 -->
    英文星期:{{ today | date:'EEEE' }} <!-- Thursday -->
    英文星期簡寫:{{ today | date:'EEE' }} <!-- Thu -->
    ? 小時格式化
    24小時制數字小時:{{today|date:'HH'}} <!--00-->
    一天中的第幾個小時:{{today|date:'H'}} <!--0-->
    12小時制數字小時:{{today|date:'hh'}} <!--12-->
    上午或下午的第幾個小時:{{today|date:'h'}} <!--12-->
    ? 分鐘格式化
    數字分鐘數:{{ today | date:'mm' }} <!-- 09 -->
    一個小時中的第幾分鐘:{{ today | date:'m' }} <!-- 9 -->
    ? 秒數格式化
    數字秒數:{{ today | date:'ss' }} <!-- 02 -->
    一分鐘內的第幾秒:{{ today | date:'s' }} <!-- 2 -->
    毫秒數:{{ today | date:'.sss' }} <!-- .995 -->
    ? 字符格式化
    上下午標識:{{ today | date:'a' }} <!-- AM -->
    四位時區(qū)標識:{{ today | date:'Z' }} <!--- 0700 -->
    下面是一些自定義日期格式的示例:
    {{ today | date:'MMMd, y' }} <!-- Aug9, 2013 -->
    {{ today | date:'EEEE, d, M' }} <!-- Thursday, 9, 8-->
    {{ today | date:'hh:mm:ss.sss' }} <!-- 12:09:02.995 -->

filter

filter過濾器可以從給定數組中選擇一個子集,并將其生成一個新數組返回。這個過濾器通常用來過濾需要進行展示的元素。例如,在客戶端搜索時,可以從一個數組中立刻過濾出所需要的結果。

這個過濾器的第一個參數可以是字符串,對象或是一個用來從數組中選擇元素的函數。

json

limitTO

lowercase

number

orderBy

uppercase

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容