1. 程式人生 > >AangularJS入門總結三

AangularJS入門總結三

align directive 使用方式 數據結構 指令 監聽 性能問題 資料 watch

(參考的資料)

1. 數據綁定的原理:

   (1) $watch 隊列: 在DOM中每次綁定一些東西,就會往$watch隊列中插入一條$watch;

            每一個綁定到了DOM上的數據都會生成一個$watch;我們的模版加載完畢時,在linking階段(Angular分為compile階段和linking階段),

            Angular解釋器會尋找每個directive,然後生成每個需要的$watch。

   (2) $digest 循環:當瀏覽器接收到可以被angular context處理的事件時,$digest循環就會觸發;

            這個循環是由兩個更小的循環組合起來的。一個處理evalAsync隊列,另一個處理$watch隊列。 

            處理$watch隊列:循環$watch 隊列,發現這個隊列中的值有變化,就執行回調函數,執行相應的DOM操作;  

                    如果有至少一個更新過,這個循環就會再次觸發,直到所有的$watch都沒有變化。這樣就能夠保證每個model都已經不會再變化。

                    如果循環超過10次的話,它將會拋出一個異常,防止無限循環。當$digest循環結束時,DOM相應地變化;  

                    (ng-click不生成$watch(函數是不會變的));  

   (3) $apply : $apply決定什麽事件進入 angular上下文環境;、

             當事件觸發時,你調用$apply,它會進入angular context,如果沒有調用就不會進入。

             當你點擊帶有ng-click的元素時,就會被封裝到一個$apply調用。如果你有一個ng-model="foo"的輸入框,然後你敲一個f,

             事件就會這樣調用$apply("foo = ‘f‘;")。

             Angular什麽時候不會自動為我們調用$apply呢?Angular不會更新我綁定的東西的解決方法scope.$apply(function() {});

             $apply是我們的$scope(或者是direcvie裏的link函數中的scope)的一個函數,調用它會強制一次$digest循環

             (除非當前正在執行循環,這種情況下會拋出一個異常)。

2. 自定義指令:angular通過指令的方式實現了HTML的擴展

       指令在框架中的執行流程:

          --瀏覽器得到 HTML 字符串內容,解析得到 DOM 結構。

          --Angular引入,把 DOM 結構扔給 $compile 函數處理:

             ---找出 DOM 結構中有變量的占位符;

             ---匹配找出 DOM 中包含的所有指令引用

             ---把指令關聯到 DOM;

             ---關聯到 DOM 的多個指令按權重排列;

             ---執行指令中的 compile 函數(改變 DOM 結構,返回 link 函數);

             ---得到的所有 link 函數組成一個列表作為 $compile 函數的返回。

          --執行 link 函數(連接模板的 scope)。

             ---註意區別一下$compile和compile,前者是Angular內部的編譯服務,後者是指令中的編譯函數,兩者發揮作用的範圍不同。

               compile 和 link 函數息息相關又有所區別;

              Angular編譯的工作是解析指令、綁定監聽器、替換模板中的變量等。工作方式很像高級語言編輯中的遞歸、堆棧過程,所以起名為編譯;

        指令的使用方式及命名方法:

            指令的幾種使用方式如下:(常用的就是作為 標簽 和 屬性)

              作為標簽:<my-dir></my-dir>

              作為屬性:<span my-dir="exp"></span>

              作為註釋:<!-- directive: my-dir exp -->

              作為類名:<span class="my-dir: exp;"></span>

              指令命名時用駝峰規則,使用時用-分割各單詞。如:定義myDirective,使用時像這樣:<my-directive>;

        自定義指令的配置參數:

              下面是定義一個標準指令的示例,可配置的參數包括以下部分:

                myModule.directive(‘namespaceDirectiveName‘, function factory(injectables) {

                 var directiveDefinitionObject = {

                   restrict: string,       //指令的使用方式,包括標簽,屬性,類,註釋

                   priority: number,       //指令執行的優先級

                  template: string,       //指令使用的模板,用HTML字符串的形式表示

                  templateUrl: string,      //從指定的url地址加載模板

                   replace: bool,       //是否用模板替換當前元素,若為false,則append在當前元素上

                   transclude: bool,      //是否將當前元素的內容轉移到模板中

                   scope: bool or object,   //指定指令的作用域

                   controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},  //定義與其他指令進行交互的接口函數

                  require: string,      //指定需要依賴的其他指令

                       link: function postLink(scope, iElement, iAttrs) {...},                //以編程的方式操作DOM,包括添加監聽器等

                   compile: function compile(tElement, tAttrs, transclude){

                         return: {

                               pre: function preLink(scope, iElement, iAttrs, controller){...},

                               post: function postLink(scope, iElement, iAttrs, controller){...}

                            }

                       }                                  //編程的方式修改DOM模板的副本,可以返回鏈接函數;

                 };

                 return directiveDefinitionObject;

                 });

                (根據自己的需要來選擇使用哪些參數。priority和compile用的比較少,template和templateUrl又是互斥的,兩者選其一即可

                    指令的表現配置參數:restrict、template、templateUrl、replace、transclude;

                    指令的行為配置參數:compile 和 link;

                    指令劃分作用域配置參數:scope;

                    指令間通信配置參數:controller和require。

            指令的表現參數restrict、template、templateUrl、replace、transclude

              transclude:指定了transclude為true,並在模板標簽上面使用了ng-transclude指令,用來告訴指令把內容轉移到的位置;

              restirct用來指定指令的使用類型,其取值及含義:

取值

含義

使用示例

E

標簽

<my-menu title=Products></my-menu>

A

屬性

<div my-menu=Products></div>

C

<div class="my-menu":Products></div>

M

註釋

<!--directive:my-menu Products-->

             指令的行為參數:compile 和 link:

                如果指令只進行DOM的修改,不進行數據綁定,那麽配置在compile函數中,如果指令要進行數據綁定,那麽配置在link函數中。

                compile拿到的是編譯前的,是從template裏拿過來的,link拿到的是編譯後的,已經與作用域建立了關聯,這也正是link中可以進行數據綁定的原因。

             指令的劃分作用域參數:scope:

                作用是描述指令與父作用域的關系;

                指令與父作用域(就是控制器所管轄的範圍)的關系可以有如下取值:

取值

說明

false

默認值。使用父作用域作為自己的作用域

true

新建一個作用域,該作用域繼承父作用域

javascript對象

與父作用域隔離,並指定可以從父作用域訪問的變量

                綁定策略,它的取值按照如下的規則:

符號

說明

舉例

      @

傳遞一個字符串作為屬性的值

str : [email protected]

      =

使用父作用域中的一個屬性,綁定數據到指令的屬性中

name : ‘=username’

      &

使用父作用域中的一個函數,可以在指令中調用

getName : ‘&getUserName’

                  自定義指令中的 scope; 用符號前綴來說明如何為指令傳值;

                   scope : {
              name : ‘=username’
             },

            指令間通信參數:controller 和 require:

                  當想做的組件稍微復雜一點,就不是一個指令可以搞定的了,就需要指令與指令的協作才可以完成,這就需要進行指令間通信;

                  controller 數用於定義指令對外提供的接口,它的寫法如下:

                        controller: function controllerConstructor($scope, $element, $attrs, $transclude){}

                  require:它的值是一個字符串,就是所依賴的指令的名字,這樣框架就能按照你指定的名字來從對應的指令上面尋找定義好的controller了。

                       不過還稍稍有點特別的地方,為了讓框架尋找的時候更輕松些,我們可以在名字前面加個小小的前綴:^,表示從父節點上尋找,

                       使用起來像這樣:require : ‘^directiveName’,如果不加,$compile服務只會從節點本身尋找。

                       另外還可以使用前綴:?,此前綴將告訴$compile服務,如果所需的controller沒找到,不要拋出異常。

3. 性能:

     缺點:當處理包含復雜數據結構的大型列表時,其運行速度就會非常慢;

      兩個主要性能問題:一個與“ng-repeat ”指令有關,另一個與過濾器有關;

      最好的辦法是限制所顯示列表的大小。可通過分頁、添加無限滾動條來實現;

      分頁,我們可以使用AngularJS的“limitTo”過濾器(AngularJS1.1.4版本以後)和“startFrom”過濾器。可以通過限制顯示列表的大小來減少渲染時間。這是減少渲染時間最高效的方法。

AangularJS入門總結三