angularJS 事件廣播與接收[轉]


 

路由的事件

    事件這個詞在前端出現的頻率真是高,根本攔不住,哪都是.$route服務在路由過程中的每個階段都會觸發不同的事件,可以為這些不同的路由事件設置監聽器並做出響應.

    一共有4個事件用來監聽路由的狀態變化: $routeStartChange, $routeChangeSuccess, $routeChangeError, $routeUpdate.

    其中最常用的是前兩個,這里稍微解釋一下.

    (1) $routeStartChange

    看名字就能猜出來它表示的是路由開始變化的事件,在瀏覽器地址欄發生變化之前AngularJS會先廣播一下這個事件.路由會開始加載所有需要的依賴,模板和resolve部分的內容也會注入.

1
2
3
4
5
6
angular.module( 'myApp' , [])
   .run([ '$rootScope' '$location' function ($rootScope, $location){
     $rootScope.$on( '$routeChangeStart' function (evt, next, current){
     console.log( 'route begin change' );
   }); 
}]);

 

    解釋一下事件的參數,evt是事件對象,可以從中讀取到一些route的信息.next是將要導航到的路由,current是當前的URL.

    可以看見在這個時期我們可以做很多有用的事,因為此時僅僅是路由開始變化,對應的內容都還沒來得及發生改變.這里我們可進行permission的校驗,loading畫面的加載,對應路由信息的讀取等等.

    (2) $routeChangeSuccess

    在路由的所有依賴都被注入加載后,AngularJS會對外廣播路由跳轉成功的事件.

1
2
3
4
5
6
angular.module( 'myApp' , [])
   .run([ '$rootScope' '$location' function ($rootScope, $location) {
     $rootScope.$on( '$routeChangeSuccess' function (evt, current, previous) {
       console.log( 'route have already changed' );
     }); 
}])

 

    這里也稍微解釋下三個參數,evt是AngularJS事件對象,current是當前所處路由,previous是上一個路由.

    剩下兩個不太常用的事件,大家去看官方API說明吧,這里不介紹了

----------------------------------------------------------------------

  • $emit只能向parent controller傳遞event與data( $emit(name, args) )
  • $broadcast只能向child controller傳遞event與data( $broadcast(name, args) )
  • $on用於接收event與data( $on(name, listener) )
 

本節課程源碼:

1
2
3
4
5
6
7
8
9
10
     
< div ng-controller = "ParentCtrl" >              <!--父級-->
   < div ng-controller = "SelfCtrl" >              <!--自己-->
     < a ng-click = "click()" >click me</ a >
     < div ng-controller = "ChildCtrl" ></ div >     <!--子級-->
   </ div >
   < div ng-controller = "BroCtrl" ></ div >         <!--平級-->
</ div >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var app = angular.module( 'myApp' , []);
app.controller( 'SelfCtrl' , function ($scope) {
   $scope.click = function () {
     $scope.$broadcast( 'to-child' , 'child' );
     $scope.$emit( 'to-parent' , 'parent' );
   }
});
 
app.controller( 'ParentCtrl' , function ($scope) {
   $scope.$on( 'to-parent' , function (event,data) {
     console.log( 'ParentCtrl' , data);       //父級能得到值
   });
   $scope.$on( 'to-child' , function (event,data) {
     console.log( 'ParentCtrl' , data);       //子級得不到值
   });
});
 
app.controller( 'ChildCtrl' , function ($scope){
   $scope.$on( 'to-child' , function (event,data) {
     console.log( 'ChildCtrl' , data);      //子級能得到值
   });
   $scope.$on( 'to-parent' , function (event,data) {
     console.log( 'ChildCtrl' , data);      //父級得不到值
   });
});
 
app.controller( 'BroCtrl' , function ($scope){
   $scope.$on( 'to-parent' , function (event,data) {
     console.log( 'BroCtrl' , data);         //平級得不到值
   });
   $scope.$on( 'to-child' , function (event,data) {
     console.log( 'BroCtrl' , data);         //平級得不到值
   });
});

在$on的方法中的event事件參數,其對象的屬性和方法如下

事件屬性 目的
event.targetScope 發出或者傳播原始事件的作用域
event.currentScope 目前正在處理的事件的作用域
event.name 事件名稱
event.stopPropagation() 一個防止事件進一步傳播(冒泡/捕獲)的函數(這只適用於使用`$emit`發出的事件)
event.preventDefault() 這個方法實際上不會做什么事,但是會設置`defaultPrevented`為true。直到事件監聽器的實現者采取行動之前它才會檢查`defaultPrevented`的值。
event.defaultPrevented 如果調用了`preventDefault`則為true

----------------------------------------------------------

 

父傳($scope.$broadcast)子接收($scope.$on)
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope', function($scope) {
$scope.message = "Child updated from parent controller";

$scope.clickFunction = function() {
$scope.$broadcast('update_parent_controller', $scope.message);
};
}
])
.controller('ChildCtrl', ['$scope', function($scope) {
$scope.message = "Some text in child controller";

$scope.$on("update_parent_controller", function(event, message) {
$scope.message = message;
});
}
]);

Here a plunker for a live demo.

Instead, if it need to send data from the SecondController (child) to the FirstController (parent), it should use the $emit method.
Here the javascript code:
子傳($scope.$emit)父接收($scope.$on)
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});

}])
.controller('ChildCtrl', ['$scope', function ($scope) {
$scope.clickFunction = function() {
$scope.message = "Parent updated";

$scope.$emit('update_parent_controller', $scope.message);
}

}]);

Here a plunker for a live demo.

Finally, here a little trick where two controller have no parent/child relationship.
It should pass data from one controller through $rootScope and the $broadcast method.
Here the javascript code:
兄弟傳($rootScope.$broadcast)兄弟接收($rootScope.$on)
angular.module('myApp', [])
.controller('FirstCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.message = "Clicked!";

$rootScope.clickFunction = function() {
$rootScope.$broadcast("Update", $scope.message);
};
}])
.controller('SecondCtrl', ['$scope','$rootScope', function($scope,$rootScope) {
$scope.message = "Waiting for a click...";

$rootScope.$on("Update", function(event, message) {
$scope.message = message;
});
}]);

Here a plunker for a live demo.

 

----------------------------------------------------------------------------------

 

 

 

 

發送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data);

接收消息: $scope.on(name,function(event,data){ });

區別: $emit 廣播給父controller   $broadcast 廣播給子controller

 

broadcast 是從發送者向他的子scope廣播一個事件。

這里就是ParentController發送, ParentController 和 ChildController 會接受到, 而MainController是不會收到的

 

$emit 廣播給父controller,父controller 是可以收到消息

$on 有兩個參數function(event,msg)  第一個參數是事件對象,第二個參數是接收到消息信息

 

復制代碼
var app = angular.module('onBroadcastEvent', ['ng']);

app.controller('MainController', function($scope) {
    $scope.$on('To-MainController', function(event,msg) {
        console.log('MainController received:' + msg);
    });
});

app.controller('ParentController', function($scope) {
    $scope.click = function (msg) {
        $scope.$emit('To-MainController',msg + ',from ParentController to MainController');
        $scope.$broadcast('To-ChildController', msg + ',from ParentController to ChildController');
        $scope.$broadcast('To-BrotherController', msg + ',from ParentController to BrotherController');
    }
});

app.controller('ChildController', function($scope){
    $scope.$on('To-ChildController', function(event,msg) {
        console.log('ChildController received:' + msg);
    });
});

app.controller('BrotherController', function($scope){
    $scope.$on('To-BrotherController', function(event, msg) {
        console.log('BrotherController received:' + msg);
    });
});
復制代碼
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM