本節書摘來自華章出版社《angularjs實戰》一 書中的第3章,第3.3節,作者:陶國榮,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
在前面的章節中我們曾經介紹過$scope對象,确切來說,它的實質就是一個作用域對象。從對這個對象的使用,我們發現作用域能存儲資料模型、為表達式提供上下文環境和監聽表達式的變化并且傳播事件,它是頁面視圖與控制器之間的重要橋梁,也是掌握angular必須知道的基礎概念,接下來,我們詳細介紹它的基礎功能和在dom中的使用方法。
具體來說,作用域包括下列3個比較顯著的特點。
它提供了一個$watch方法來監聽資料模型的變化,之是以能使用“ng-model”指令實作資料的雙向綁定,就是通過調用該方法進行資料模型的監聽,隻要有一端發生變化,另外綁定的一端自動進行資料同步。
它提供另外一個$apply方法,為各種類型的資料模型改變提供支撐,将它們引入到angular可控制器的範圍中。最典型的就是控制器,例如,通過頁面視圖模闆中“ng-click”指令,執行控制器中的代碼。
它為表達式提供了執行的環境,一個表達式必須在擁有該表達式屬性的作用域中執行才更加合适,作用域通過提供$scope對象,使所有的表達式都擁有對應的執行環境,也就是執行的上下文對象。
接下來,通過一個完整的示例來介紹作用域下調用$watch方法監聽資料子產品的變化。
示例3-6 $watch方法的使用
(1)功能描述
當在頁面的文本框中輸入任意“姓名”字元時,另一個
元素中将顯示輸入框中字元變化的累計次數。
(2)實作代碼
建立一個html檔案3-6.html,加入如代碼清單3-6所示的代碼。
代碼清單3-6 $watch方法
(3)頁面效果
執行html檔案3-6.html,最終實作的頁面效果如圖3-6所示。
(4)源碼分析
在本示例的源碼中,當在頁面的控制器中編寫代碼時,先定義兩個$scope對象的屬性“name”和“count”,前者用于使用“ng-model”指令綁定文本框中的内容,後者用于記錄文本框中字元内容變化的累計次數。
然後,使用作用域中的$watch方法對$scope中的“name”屬性進行監視,當該屬性值發生變化時,将$scope中的“count”屬性值累加1,是以,隻要在文本輸入框中做任何一次的修改,都會通過“count”屬性值回報至頁面中。

之是以可以通過$watch方法監控模型資料發生的變化,主要是因為在angular的内部,每當我們對已綁定“ng-model”指令的“name”屬性進行修改時,其内部的$digest方法就會自動運作一次,檢測已綁定的“name”屬性是否與上一次$digest方法運作時擷取的内容一緻。如果不一緻,則執行$watch方法綁定的處理函數,即将“count”屬性值累加1。
在前面的章節中我們曾說過,作用域是控制器與視圖的橋梁。不僅如此,它也是視圖和指令的橋梁。因為在自定義指令時,會調用$watch方法監聽各個表達式的變化,一旦作用域中的表達式發生了變化,$watch方法将通知指令,而指令将根據這個變化重新渲染dom頁面,即更新作用域中的屬性值内容。
無論是指令,還是控制器,它們都可以通過作用域與視圖中的dom綁定。由此,誕生了兩個資料關系鍊,一條是:指令——>作用域——>視圖;另一條是:控制器——>作用域——>視圖。這兩條關系鍊之間還是互相獨立的。
接下來,通過一個簡單的示例來介紹控制器借助作用域控制視圖中元素的顯示内容。
示例3-7 作為資料模型的作用域
當在頁面的文本框中輸入内容時,
元素通過雙花括号綁定的方式自動同步該内容,并将它顯示在元素中。
建立一個html檔案3-7.html,加入如代碼清單3-7所示的代碼。
代碼清單3-7 作為資料模型的作用域
執行html檔案3-7.html,最終實作的頁面效果如圖3-7所示。
在上述示例的源代碼中,先通過頁面子產品定義了一個名為“c3_7”的控制器,在控制器中引用$scope對象注冊了一個名為“name”的屬性,而$scope對象則通過注冊的屬性,控制了頁面所需的資料模型,視圖模闆則通過雙向綁定的方式傳遞并顯示資料模型中的屬性值。
接下來,分别從控制器和視圖這兩個角度來分析這個示例的具體流程。從控制器的角度來說,首先,通過$scope對象為“name”屬性賦初始值;然後,通過$watch方法通知視圖中的文本輸入框元素資料已發生了變化,而文本框元素使用“ng-model”指令實作了資料的雙向綁定。是以,它可以獲悉該變化,并自動同步變化後的“name”屬性值,且該值渲染至文本框中。
從視圖的角度來說,由于文本框通過“ng-model”指令進行了資料的雙向綁定,是以,先通過$scope對象擷取控制器中“name”屬性值;然後,如果使用者在文本框中輸入了新的内容,則會自動将該内容傳遞給控制器中的“name”屬性,保持兩端的資料同步。
此外,在
元素中使用雙花括号的方式綁定“name”屬性,該方式分為取值和計算兩個階段,在取值時,雙花括号中的表達式将會根據$scope對象尋找所屬的控制器,并在控制器中找到添加的“name”屬性;取值後,在控制器中進行計算,并将結果返給$scope對象,視圖模闆中通過$scope擷取最終值并進行渲染,最終顯示在頁面的元素中。