在Angularjs應用程序中,一個頁面通常被劃分為很多個區域,每個區域對應一個控制器,同級控制器之間互不干擾。有時候我們希望一個控制器中的內容改變的同時其他的控制器也作出響應,這時就要在控制器之間進行通信了。
一.利用作用域的繼承方式
由於Angularjs中作用域的繼承是基於js的原型繼承方式,所以這裡分為兩種情況,當作用域上面的值為基本類型的時候,修改父作用域上面的值會影響到子作用域,反之,修改子作用域只會影響子作用域的值,不會影響父作用域上面的值;如果需要父作用域與子作用域共享一個值的話,就需要用到後面一種,即作用域上的值為對象,任何一方的修改都能影響另一方,這是因為在js中對象都是引用類型。
圖1
如圖1是HTML頁面的部分內容,Child控制器會繼承Father控制器的值。當繼承的值為基本類型時(圖2),點擊第一個“更改地區”,兩個綁定的location的值都變成了“深圳”,點擊第二個“更改地區”時,第一個location的值不變,第二個變成了“廣州”。如果想要兩個location的值都改變,可以把location裝到一個對象裡,如圖3。對應HTML內容把綁定的內容改成 obj.location。
圖2
圖3
二.基於事件的方式
在一般情況下基於繼承的方式已經足夠滿足大部分情況了,但是這種方式沒有實現兄弟控制器之間的通信方式,所以引出了事件的方式。基於事件的方式中我們可以利用Angularjs定義好的$on,$emit,$boardcast這幾個事件處理函數來實現,其中$on表示事件監聽,$emit表示向父級以上的作用域傳播事件, $boardcast表示向子級以下的作用域廣播事件。如圖4部分HTML頁面:Father控制器作用域下有兩個子控制器作用域Child1、Child2,對應的js如圖5。
圖4
圖5
當點擊任何一個“更改地區”的按鈕時,對應的控制器會向父級以上控制器傳播一個“changeLocation”事件,圖5中的Father控制器剛好有監聽該事件,當Father控制器監聽到“changeLocation”事件時,它做出的響應是向子控制器廣播一個事件“onChangeLocation”,圖5中兩個子控制器都監聽了“onChangeLocation”事件,分別對事件做出響應。最後頁面上第一個綁定的值顯示“廣州”,第二個顯示“深圳”。這裡要特別注意的是,通過父元素作為中介進行傳遞的話,廣播的事件名不能和監聽到的事件名相同。
三.基於服務的方式
在Angularjs中服務是一個單例,所以在服務中生成一個對象,該對象就可以利用依賴注入的方式在所有的控制器中共享。參照以下例子,在一個控制器修改了服務對象的值,在另一個控制器中就可以獲取到修改後的值。HTML及對應的JS如圖6、圖7。當在輸入框中輸入文字,點擊“click me”時,頁面上name的值變成了輸入的文字。
圖6
圖7