angular companent 組件

在angularjs中,Component是一種特殊的directive,更適合組件化的app架構javascript

Component的優勢:css

  • 比普通directive要簡單不少
  • 更加嚴謹,更加規範化
  • 更加適合組件化架構
  • component更容易升級到angular2

不使用Component的狀況java

  • 須要在編譯階段和預連接階段執行的directive,由於Component這時還不可用
  • 當你須要directive纔有定義的選項時,如priority, terminal, multi-element
  • 當你須要directive由屬性,css的class而不是元素觸發時

component的建立與配置angularjs

Components由angularjs的module使用.component()方法註冊。這個方法接受2個參數:api

  • Component的名稱(字符串類型)
  • Component的配置對象(注意,和.directive()不同,不是一個工廠方法而僅僅是個配置對象)

Directive和Component之間的定義比較

屬性 Directive Component
bindings No Yes (binds to controller)
bindToController Yes (default: false) No (use bindings instead)
compile function Yes NO
controller Yes Yes (default function() {})
controllerAs Yes (default: false) Yes (default: $ctrl)
link functions Yes No
multiElement Yes No
priority Yes No
replace Yes (deprecated) No
require Yes Yes
restrict Yes No (restricted to elements only)
scope Yes (default: false) No (scope is always isolate)
template Yes Yes, injectable
templateNamespace Yes No
templateUrl Yes Yes, injectable
terminal Yes No
transclude Yes (default: false) Yes (default: false)

組件化app架構數組

component使得使用組件化架構構建app更爲容易,除此以外component還具有的能力具體以下:angular2

  • Component只能控制它本身的視圖和數據:Component不會修改它自身scope以外的任何數據或DOM。一般狀況下,AngularJS中能夠經過scope繼承和watch能夠修改任何地方的數據,這確實很實用,可是也會致使很難明確哪一個部分對修改數據負責。這就是爲何Component使用隔離範圍,也所以沒法進行全部scope的操做。
  • Component有明肯定義的公共api-輸入輸出:隔離範圍並非所有,由於AngularJS是雙向綁定的。若是你傳一個對象到組件中,相似bindings: {item: '='},而後修改對象的屬性,修改會反映到它的父組件中。可是對於component來講,component確實只是修改了它本身的scope內的數據。這樣就很清晰的得知什麼數據何時被修改。就此,component遵循一些簡單的約定:架構

 輸入  @

使用@符號能夠進行單項的數據綁定,取值老是一個字符串,因此要用{{}}。app

另外這也是一個單向的綁定,外部數據改變會反應到內部,可是內部數據變數據變化,外部不會變。異步

屬性要用-鏈接,scope中寫它的駝峯格式。

若是沒有經過@attr指定屬性名稱,那麼本地名稱要與DOM屬性的名稱一致。

 <

在1.5以後表示單向綁定,它綁定的屬性在component的scope哪不會被watch,

這意味着你能夠在component的scope內給屬性設置一個新的值,

它並不會更新父scope裏的值。可是若是父scope和component的scope引用的是同一個對象,

好比你在component修改對象的屬性或者數組中的元素,這種改變仍然會反映到父scope。

所以在<綁定後不要在component內修改對象的屬性和數組的元素

=

使用=進行雙向數據綁定,任何一方的值改變都會反應到另外一方。由於是雙向綁定,因此不要使用{{}},否則會報錯。

屬性要用-鏈接,scope中寫它的駝峯格式。

若是沒有經過@attr指定屬性名稱,那麼本地名稱要與DOM屬性的名稱一致。

 輸出  &

綁定的函數將做爲component事件的回調函數

屬性要用-鏈接,scope中寫它的駝峯格式。

若是沒有經過@attr指定屬性名稱,那麼本地名稱要與DOM屬性的名稱一致。

1 bindings: {
2     hero: '<',
3     comment: '@'
4 } 
bindings: {
    onDelete: '&',
    onUpdate: '&'
}

三、在不操做輸入數據的狀況下,component能夠調用相應的輸出事件改變輸出數據。好比刪除,並非hero本身刪除本身,而是經過相應的事件把本身傳給父component

<editable-field on-update="$ctrl.update('location', value)"></editable-field><br>
<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>

四、component來決定事件執行什麼(刪除item仍是更新屬性)

ctrl.deleteHero(hero) {
    $http.delete(...).then(function() {
        var idx = ctrl.list.indexOf(hero);
        if (idx >= 0) {
            ctrl.list.splice(idx, 1);
        }
    }); 
}

生命週期

 

  • $onInit() - 在element上的全部controller構造和全部的綁定初始化以後,在element之上前綴&的函數連接以前,每個controller調用這個鉤子方法。這是個給controller寫一些初始化方法的好地方
  • $onChanges(changesObj) - 當單向綁定更新時調用,changesObj是一個hash鍵值對,key是已被修改的綁定屬性的name,value是一個對象,格式是{ currentValue, previousValue, isFirstChange() },使用這個hook能夠只觸發組件內的更新,好比克隆綁定屬性的對象以防止它被外部意外更新
  • $doCheck() - 在每個digest循環被調用,提供了一個機會能夠在數據更改時驗證或者作一些操做。任何你但願進行的操做(好比對更改的響應)都必須經過這個hook調用。當$onChanges被調用時,實現這個hook沒什麼做用。好比,好比你想實現一個深度的equal函數檢查,或者檢查一個Date對象時,他將會很是有用,由於這是AngularJS的變化檢測器檢測不到這個變化,天然$onChanges也不會被調用。這個hook不包含任何參數,所以,若是想要檢測變化,你須要存儲以前的值,而後和如今的值進行比較。
  • $onDestroy() - 當controller包含的scope銷燬時,controller會調用這個hook。使用這個hook能夠釋放一些外部資源,watch和事件處理程序
  • $postLink() - 在controller的element和子元素被連接後調用。和post-link函數相似,這個hook能夠設置DOM事件的處理程序或者直接進行DOM操做。包含templateUrl指令的element不會被編譯和連接,由於它們要等template異步加載。它們的編譯和連接要等template完成以後纔會執行。這個hook很是和angular2中的ngAfterViewInit和ngAfterContentInit兩個hook相似。由於angular1和angular2編譯過程的不一樣,因此在anguar1升級到angular2時必定要當心。

Component做爲route模版

當使用ngRoute時,Component做爲route的模版也是很是有用的。一個組件化的app,每個視圖都是一個組件:

 

 1 var myMod = angular.module('myMod', ['ngRoute']);
 2 myMod.component('home', {
 3   template: '<h1>Home</h1><p>Hello, {{ $ctrl.user.name }} !</p>',
 4   controller: function() {
 5     this.user = {name: 'world'};
 6   }
 7 });
 8 myMod.config(function($routeProvider) {
 9   $routeProvider.when('/', {
10     template: '<home></home>'
11   });
12 })
相關文章
相關標籤/搜索