2016-02-13 56 views
0

我正在學習angularJS廣播和發射。下面的代碼似乎不起作用,即FirstCtrl和SecondCtrl不接收廣播消息。任何Angularjs廣播和查詢

<div ng-controller="FirstCtrl"> 
    <div ng-controller="SecondCtrl"> </div>  
</div> 

var app = angular.module("myapp", []); 

function FirstCtrl($scope){ 
    this.name = "xxxx"; 
    this.age = 31; 

    $scope.$on("message", function(e, opt){ 
     console.log("received message First"); 
    }); 
} 
function SecondCtrl($scope){ 
    this.name = "yyyy"; 
    this.age = 31; 
    $scope.$on("message", function(e, opt){ 
     console.log("received message second"); 
    }); 

} 

app.controller("FirstCtrl", FirstCtrl); 
app.controller("SecondCtrl", SecondCtrl); 
app.run(function($rootScope){ 
    $rootScope.$on("message", function(e,opt){ 
     console.log("root receive message"); 
    }); 

    $rootScope.$broadcast("message", { message : "root broadcast"}); 
}); 

回答

1

你的例子說明了一個重要的觀點。控制器在應用程序的生命週期中被創建和銷燬。他們可能錯過廣播事件。在另一手服務是單身人士並可用於應用程序的整個生命週期。因此,將您的活動記錄在服務中。

app.factory("messageService", function($rootScope) { 
    var lastMessage = {}; 
    function getMessage() { return lastMessage }; 
    function setMessage(m) { lastMessage = m }; 
    //record events 
    $rootScope.$on("message" function(e,opt) { 
      lastMessage.event = e; 
      lastMessage.opt = opt; 
    }); 
    return { getMessage: getMessage, 
       setMessage: setMessage 
      }; 
}); 

您的控制器可以「趕上」並訂閱事件。

app.controller("FirstCtrl", function($scope,messageService) { 
    //catch-up 
    var message = messageService.getMessage(); 
    console.log(message.opt.message); 
    //subscribe 
    $scope.$on("message", function (e,opt) { 
      message.event = e; 
      message.opt = opt; 
      console.log(message.opt.message); 
    }); 
}); 

在您的運行區塊中一定要注入messageService

app.run(function($rootScope, messageService){ 
    $rootScope.$on("message", function(e,opt){ 
     console.log("root receive message"); 
    }); 

    $rootScope.$broadcast("message", { message : "root broadcast"}); 
}); 

AngularJS框架確實實現了服務的惰性實例化。即使跑塊沒有使用messageService,它也需要實例化來接收和記錄廣播事件。

1

發生這種情況,因爲當run塊被執行,沒有一個控制器已被實例化。

要解決此問題,使用$timeout以便有足夠的時間允許的控制器被實例化:

$timeout(function() { 
    $rootScope.$broadcast("message", { message : "root broadcast"}); 
}, 100) 
0

或者,您可以使用angular-PubSub來避免將事件發送到超過必要的控制器。

$rootScope.$broadcast將發送事件給所有範圍,如果您有很多控制器/範圍,可能效率不高。在這種情況下,建議高效使用PubSub模式。

注意不要忘記取消訂閱事件/主題,以避免內存泄漏。