angularjs中controller之間的通信

不同框架實現(xiàn)的功能都是相似的野舶,只不過方法不同峦耘,這就為我們了解不同框架砌们,從一個框架向另一個框架學習提供了方便贩虾。比如說頁面之間的傳值催烘,看了vuex之后就在想angular實現(xiàn)類似的功能應該怎么做。
在angular中缎罢,實現(xiàn)controller之間傳值的方式大致有三種:

  • 注入服務伊群。把需要共享的數(shù)據注冊為一個service,在需要的controller中注入策精。
  • 基于事件舰始。利用angular中的事件機制,使用$on咽袜,$boardcast丸卷,$emit。
  • 作用域繼承询刹。利用子controller控制父controller上的數(shù)據谜嫉。

在大項目中應該使用注入服務(推薦),小項目中可以使用基于事件的傳值(事件多了很繁瑣凹联,不利于高內聚沐兰、低耦合),作用域繼承不推薦(很大的局限性)蔽挠。

注入服務

在Angular里面僧鲁,services作為單例對象在需要到的時候被創(chuàng)建,只有在應用生命周期結束的時候(關閉瀏覽器)才會被清除象泵。而controllers在不需要的時候就會被銷毀了寞秃。所以在服務中生成一個對象,該對象就可以利用依賴注入的方式在所有的控制器中共享偶惠。

看個栗子春寿,先定義一個 service :

angular.module('demo')
    .factory('Data', function(){
        return {
            name: 'htf'
        };
    })

頁面:

<div ng-controller="childCtrl1">
  <h3>data in child controller 1 : {{data.name}}</h3>
  <input class="form-control" type="text" ng-model="data.name">
</div>
<div ng-controller="childCtrl2">
  <h3>data in child controller 2 : {{data.name}}</h3>
  <input class="form-control" type="text" ng-model="data.name">
</div>

控制器:

.controller('childCtrl1', ['$scope', 'Data', function($scope, Data){
    $scope.data = Data;
}])

.controller('childCtrl2', ['$scope', 'Data', function($scope, Data){
    $scope.data = Data;
}])

這種方式適用于任何需要通信的 Controller 之間。

基于事件

Angular 為 $scope 提供了冒泡和隧道機制忽孽,$broadcast 會把事件廣播給所有子 Controller绑改,而 $emit 則會將事件冒泡傳遞給父 Controller,$on 則是 Angular 的事件監(jiān)聽函數(shù)兄一,利用這三者厘线,可以實現(xiàn)上下級和同級(需要構造一個共同的父級 Controller)之間的通信。

上下級之間

這種情況下比較簡單出革。

如果是子 Controller 往父 Controller 上發(fā)送事件(從作用域往上發(fā)送事件)造壮,使用 scope.$emit

$scope.$emit("someEvent", {});

如果是父 Controller 往子 Controller 上發(fā)送事件(從作用域往下發(fā)送事件),使用 scope.$broadcast

$scope.$broadcast("someEvent", {});

無論是 $emit 還是 $broadcast 發(fā)送的事件,都用 $scope.$on 接收:

$scope.$on("someEvent", function(event, data) {
    // 這里取到發(fā)送過來的數(shù)據 data
});

同級之間

同級之間利用事件通信有兩種方法耳璧。一種是利用上下級之間事件傳播的變形成箫,另一種是借助 $rootScope 。

借助父 controller

先看第一種旨枯,在子 Controller 中向父 Controller 觸發(fā)一個事件蹬昌,然后在父 Controller 中監(jiān)聽事件,再廣播給子 Controller 攀隔,這樣通過事件攜帶的參數(shù)皂贩,實現(xiàn)了數(shù)據經過父 Controller,在同級 Controller 之間傳播昆汹。

但是要注意明刷,通過父 Controller 作為中介進行傳遞的話,子 Controller 觸發(fā)的事件名和父 Controller 廣播用的事件名不能一樣筹煮,否則會進入死循環(huán)。

看代碼:

<div ng-controller="outerCtrl">
  <h3>data in outer controller: {{name}}</h3>
  <div ng-controller="innerCtrl1">
    <input class="form-control" type="text" ng-model="name" ng-change="change()">
  </div>
  <div ng-controller="innerCtrl2">
    <input class="form-control" type="text" ng-model="name" ng-change="change()">
  </div>
</div>

關鍵部分在控制器:

.controller('outerCtrl', ['$scope', function($scope){
    $scope.name = 'htf';
    $scope.$on('dataChanged', function(event, data){
        $scope.name = data;
        // 2. 父 Ctrl 監(jiān)聽到 dataChanged 時間后居夹,觸發(fā) changeData 事件
        $scope.$broadcast('changeData', data);
    })
}])

.controller('innerCtrl1', ['$scope', function($scope){
    $scope.change = function(){
        // 1. 子 Ctrl1 中數(shù)據改變之后觸發(fā) dataChanged 事件
        $scope.$emit('dataChanged', $scope.name);
    }
    $scope.$on('changeData', function(event, data){
        $scope.name = data;
    })
}])

.controller('innerCtrl2', ['$scope', function($scope){
    $scope.change = function(){
        $scope.$emit('dataChanged', $scope.name);
    }
    // 3. 監(jiān)聽到 changeData 事件后败潦,改變子 Ctrl2 中 數(shù)據
    $scope.$on('changeData', function(event, data){
        $scope.name = data;
    })
}])

借助 $rootScope

每個 Angular 應用默認有一個根作用域 $rootScope, 根作用域位于最頂層准脂,從它往下掛著各級作用域劫扒。

所以,如果子控制器直接使用 $rootScope 廣播和接收事件狸膏,那么就可實現(xiàn)同級之間的通信沟饥。

看栗子:

<div ng-controller="innerCtrlA">
    <input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>
<div ng-controller="innerCtrlB">
    <input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>

控制器:

.controller('innerCtrlA', ['$scope', '$rootScope', function($scope, $rootScope){
    $scope.change = function(){
        // 廣播事件
        $rootScope.$broadcast('nameChanged', $scope.name);
    }
    $rootScope.$on('nameChanged', function(event, data){
        $scope.name = data;
    })
}])

.controller('innerCtrlB', ['$scope', '$rootScope', function($scope, $rootScope){
    $scope.change = function(){
        $rootScope.$broadcast('nameChanged', $scope.name);
    }
    // 監(jiān)聽事件
    $rootScope.$on('nameChanged', function(event, data){
        $scope.name = data;
    })
}])

作用域繼承

每個 Angular 應用默認有一個根作用域 $rootScope, 根作用域位于最頂層湾戳,從它往下掛著各級作用域贤旷。

通常情況下,頁面中 ng-model 綁定的變量都是在對應的 Controller 中定義的砾脑。如果一個變量未在當前作用域中定義幼驶,JavaScript 會通過當前 Controller 的 prototype 向上查找,也就是作用域的繼承韧衣。

頁面:

<div ng-controller="parentCtrl">
  <p>data in parent controller : {{data.name}}</p>
  <div ng-controller="childCtrl">
    <input type="text" ng-model="data.name">
  </div>
</div>

控制器:

angular.module('demo', [])

.controller('parentCtrl', ['$scope', function($scope){
    $scope.data = {
        name: 'htf'
    }
}])

.controller('childCtrl', ['$scope', function($scope){

}])

以上是父 Controller 中的數(shù)據是引用類型的情況盅藻。如果父 Controller 中的數(shù)據是基本類型,改變子controller的值父controller的值不變畅铭,可通過 $scope.$parent.data 訪問氏淑。

很顯然,這種方式僅適用于父子級間 Controller 的通信硕噩。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末假残,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子炉擅,更是在濱河造成了極大的恐慌守问,老刑警劉巖匀归,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耗帕,居然都是意外死亡穆端,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門仿便,熙熙樓的掌柜王于貴愁眉苦臉地迎上來体啰,“玉大人,你說我怎么就攤上這事嗽仪』挠拢” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵闻坚,是天一觀的道長沽翔。 經常有香客問我,道長窿凤,這世上最難降的妖魔是什么仅偎? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮雳殊,結果婚禮上橘沥,老公的妹妹穿的比我還像新娘。我一直安慰自己夯秃,他們只是感情好座咆,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仓洼,像睡著了一般介陶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上色建,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天斤蔓,我揣著相機與錄音,去河邊找鬼镀岛。 笑死弦牡,一個胖子當著我的面吹牛,可吹牛的內容都是我干的漂羊。 我是一名探鬼主播驾锰,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼走越!你這毒婦竟也來了椭豫?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赏酥,沒想到半個月后喳整,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡裸扶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年框都,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呵晨。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡魏保,死狀恐怖,靈堂內的尸體忽然破棺而出摸屠,到底是詐尸還是另有隱情谓罗,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布季二,位于F島的核電站檩咱,受9級特大地震影響,放射性物質發(fā)生泄漏胯舷。R本人自食惡果不足惜刻蚯,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望需纳。 院中可真熱鬧芦倒,春花似錦艺挪、人聲如沸不翩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽口蝠。三九已至,卻和暖如春津坑,著一層夾襖步出監(jiān)牢的瞬間妙蔗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工疆瑰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眉反,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓穆役,卻偏偏與公主長得像寸五,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耿币,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內容

  • 1.類庫( 提供類方法 ) 和框架 類庫提供一系列的函數(shù)和方法的合集梳杏,能夠加快你寫代碼的速度。但是主導邏輯的還是自...
    w_zhuan閱讀 1,792評論 0 8
  • 這是一個面試官問我的題目叛溢,當時沒回答出來,主要是項目中沒有碰到過這類問題劲适,因此今天整理下查找到的資料楷掉,希望對大家有...
    一木_qintb閱讀 743評論 0 2
  • Angular面試題 一、ng-show/ng-hide與ng-if的區(qū)別减响? 第一點區(qū)別是靖诗,ng-if在后面表達式...
    w_zhuan閱讀 5,530評論 0 26
  • 1、angularjs的幾大特性是什么支示? 雙向數(shù)據綁定刊橘、依賴注入、模板颂鸿、指令促绵、MVC/MVVM 2、列舉幾種常見的...
    2e9a10d418ab閱讀 1,275評論 0 10
  • 總覺得我是在書里長大的孩子。 從小就愛看書栽渴,除了那些兒時大家一起玩鬧的游戲之外尖坤,我個人的最大愛好就是兩件事了:看書...
    小小小小只閱讀 193評論 0 1