2016-02-13 55 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模式。

注意不要忘记取消订阅事件/主题,以避免内存泄漏。