预赛
我正在使用angularjs开发一个Web应用程序。在某些时候,我的主控制器连接到一个连续发送数据的Web服务。捕获和处理我正在使用的流(http://ajaxpatterns.org/HTTP_Streaming)。一切都像魅力一样。我想与另一个控制器共享这些流数据,这个控制器将通过jquery图表库处理和显示它们(尚未决定我将使用哪一个,但它超出了这个问题的范围)。为了分享这些数据,我遵循了这个jsfiddle(http://jsfiddle.net/eshepelyuk/vhKfq/)。
请在下面找到我的代码的一些相关部分。
模块,路线和服务定义:
var platform = angular.module('platform', ['ui']);
platform.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/home',{templateUrl:'partials/home.html',controller:PlatformCtrl}).
when('/visu/:idVisu', {templateUrl: 'partials/visuTimeSeries.html',controller:VisuCtrl}).
otherwise({redirectTo:'/home',templateUrl:'partials/home.html'})
}]);
platform.factory('mySharedService', function($rootScope) {
return {
broadcast: function(msg) {
$rootScope.$broadcast('handleBroadcast', msg);
}
};
});
PlatformCtrl定义:
function PlatformCtrl($scope,$http,$q,$routeParams, sharedService) {
...
$scope.listDataVisu ={};
...
$scope.listXhrReq[idVisu] = createXMLHttpRequest();
$scope.listXhrReq[idVisu].open("get", urlConnect, true);
$scope.listXhrReq[idVisu].onreadystatechange = function() {
$scope.$apply(function () {
var serverResponse = $scope.listXhrReq[idVisu].responseText;
$scope.listDataVisu[idVisu] = serverResponse.split("\n");
sharedService.broadcast($scope.listDataVisu);
});
};
$scope.listXhrReq[idVisu].send(null);
var w = window.open("#/visu/"+idVisu);
$scope.$on('handleBroadcast', function(){
console.log("handleBroadcast (platform)");
});
}
VisuCtrl定义:
function VisuCtrl($scope,$routeParams,sharedService) {
$scope.idVisu = $routeParams.idVisu;
$scope.data = [];
/* ***************************************
* LISTENER FOR THE HANDLEBROADCAST EVENT
*****************************************/
$scope.$on('handleBroadcast', function(event,data){
console.log("handleBroadcast (visu)");
$scope.data = data[$scope.idVisu];
});
}
注射:
PlatformCtrl.$inject = ['$scope','$http','$q','$routeParams','mySharedService'];
VisuCtrl.$inject = ['$scope','$routeParams','mySharedService'];
问题定义
运行此代码时,看起来只有PlatformCtrl
控制器才会侦听handleBroadcast
事件。实际上,每次新数据到达时,只需查看控制台所显示的内容,handleBroadcast (platform)
即可。我很惊讶因为我在官方文档中读到了$broadcast
函数
将事件名称向下调度到所有子范围(及其范围) 孩子们)通知听众的注册ng。$ rootScope.Scope#$。
由于给定应用中的所有范围都来自$rootScope
,因此我不明白为什么每次广播新数据时都不会启动$on
中的VisuCtrl
功能。
答案 0 :(得分:2)
我认为当您打开新的浏览器窗口时,您将启动一个新的AngularJS实例。这样,两个控制器就不可能通过服务进行通信。
如果您在范围通信方面遇到问题,可以注入$ rootScope,看看是否所有应该通信的范围实际上都是实例化的。
function VisuCtrl($scope, $routeParams, sharedService, $rootscope) {
console.log($rootScope);
}
答案 1 :(得分:0)
您的请求流出的是角度,因此在下一个$ digest阶段之前不会被识别(请参阅角度如何通过脏匹配处理双向绑定)。要进入角度世界,您需要使用$apply
:
$scope.listXhrReq[idVisu].onreadystatechange = function() {
$scope.$apply(function () {
var serverResponse = $scope.listXhrReq[idVisu].responseText;
$scope.listDataVisu[idVisu] = serverResponse.split("\n");
sharedService.broadcast($scope.listDataVisu);
});
};
答案 2 :(得分:0)
您的VisuCtrl是否尚未初始化,因为您使用的是自定义路由?
导航到/visu/:idVisu
时是否仍然相同?