AngularJS 文檔閱讀之指令 scope

scope

指令,是AngularJS最經常使用的功能,讓咱們很容易在前臺實現代碼複用。而指令最精髓的地方,就在於指令內外域scope的交互方式。javascript

本文屬於一篇對文檔的翻譯加上一些本身對此的理解,因水平有限,可能某些地方翻譯的不通順,或者翻譯的錯了,歡迎你們批評指正。本文對scope的用法以及描述均翻譯自AngularJS英文文檔,文檔地址:AngularJS 官方文檔java

scope屬性的值能夠是false,能夠是true,也能夠是對象。angularjs

false

false:這是指令scope的默認屬性,不會爲指令建立一個scope,這個指令會使用他的父scopeapi

true

true:爲指令建立一個從父scope原型繼承的子scope數組

對象

{key: value}:爲指令建立一個新的隔離scope,隔離scope和一般的scope的區別在於:隔離scope不從父scope作原型繼承。app

不從父scope作原型繼承,這對於建立可重用的組件很是有用,可重用組件不該該從父scope讀取或修改屬性。this

注意:一個有隔離scope可是沒有templatetemplateUrl的指令不會將隔離scope應用到它的子元素。這是文檔上寫的,目前尚未理解到到底是什麼意思。google

也多是我翻譯的不對,如下是原文:翻譯

Note that an isolate scope directive without a template or templateUrl will not apply the isolate scope to its children elements.

隔離對象定義了源於指令元素的屬性的本地scope屬性集合。雙向綁定

scope綁定

如下幾種綁定都是能夠加參數的。

例:

scope: {
    name: '=nameAttr'
}

綁定的就是:<test name-attr="'hello'"></test>

scope: {
    name: '='
}

綁定的就是:<test name="'hello'"></test>

字符串綁定

@/@attr:綁定本地scope的屬性到DOM屬性的值,這個結果老是一個字符串,由於DOM屬性就是字符串。隨着DOM屬性值的改變,指令scope上的屬性也會改變,由於這個屬性是在它的父scope上讀取的。

雙向綁定

=/=attr:本地scope的屬性和傳遞到屬性上的表達式創建雙向綁定,該表達式是在父scope的範圍內計算的。若是綁定的表達式不是可賦值的,或者它不是可選的可是指令中沒有傳,$compile:noassign異常就會被拋出,由於它沒法和父scope同步。

默認地,$watch方法一般用來監聽改變,而且根據對象的地址來進行相等判斷。然而,若是一個對象地址或數組地址被傳遞到綁定的表達式中,比較的方法就是經過判斷值是否相等。也可使用=*/=*attr$watchCollection進行淺監聽。

這段話還不是很理解,在StackOverflow找到了一個靠譜的回答,但還不是很明白。AngularJS =* 問題

單向綁定

</<attr:在本地scope和傳遞到DOM屬性上的表達式之間創建單向綁定,全部在DOM屬性上表達式的改變會反映到scope的屬性上,可是scope屬性上的改變不會反映到DOM屬性的表達式上。

可是這有兩個警告:

1.單向綁定不是將父scope的值拷貝到隔離scope上,而是簡單的設置相同的值。若是你傳的是一個對象,那在隔離scope上對該對象的改變會反映到父scope上,由於二者引用同一個對象。

2.單向綁定監視的是父值地址的改變。這意味着在父值上的$watch僅僅在引用的地址發生改變時纔會生效。大多數狀況下,這是不須要關心的。可是必需要知道若是你單向綁定了一個對象,而後會改變隔離scope上的對象,若是改變了父scope上的該對象的一個屬性,這個改變是不會傳遞到隔離scope上的,由於這個對象的地址沒有改變,除非你賦值一個新的對象。

若是不打算將隔離scope的改變傳播會父節點,單向綁定是頗有用的。

綁定方法

&/&attr:在父scope提供一個可執行的表達式,就是傳一個方法。

設置可選

全部的綁定(@, =, <, &)都能經過在表達式上添加?設置爲可選的,這個標誌必須在綁定模式以後,屬性名稱以前。

可選和不可選的區別在於:

  • 綁定是可選的,這個屬性不會被定義。
  • 綁定不是可選的,這個屬性被定義了。

如下是AngularJS文檔中對可選指令的示例代碼。

app.directive('testDir', function() {
  return {
    scope: {
      notoptional: '=',
      optional: '=?',
    },
    bindToController: true,
    controller: function() {
      this.$onInit = function() {
        console.log(this.hasOwnProperty('notoptional')); // true
        console.log(this.hasOwnProperty('optional')); // false
      }
    }
  };
});
相關文章
相關標籤/搜索