2013-02-15 78 views
0

预赛通信控制器之间不可能

我开发使用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继承,我不知道为什么在VisuCtrl$on功能未发布的每一个新的数据广播的时间。

+0

因此,您在/ visu /:idVisu上使用PlatformCtrl for/home和VisuCtrl,但它们仍然同时运行?这有点令人困惑:)你能帮我理解吗? – 2013-02-15 22:18:53

+0

@Flek准确地说,这个想法是打开一个弹出窗口来显示使用VisuCtrl的流数据。同时PlatformCtrl仍然会运行。 – 2013-02-16 15:20:22

+0

但是两个控制器是否真的在同一个角度实例内运行?我在问,因为如果我正确地使用了window.open,那么你打开一个新的浏览器窗口不是吗? – 2013-02-16 20:13:58

回答

2

我认为那是什么,当你打开一个新的浏览器窗口,您正在推出一个新的AngularJS实例。这样两个控制器不可能通过服务进行通信。

如果你有范围的通信出现问题,你可以注入的$ rootScope看到所有应该传达范围是否真的实例化。

function VisuCtrl($scope, $routeParams, sharedService, $rootscope) { 
    console.log($rootScope); 
} 
+0

你是对的,其实我也得出了同样的结论。当visuCtrl与PlatformCtrl在同一页面上时,两个控制器可以进行通信。一些谷歌搜索后,在javascript中创建一个多浏览器窗口应用程序看起来相当棘手。因此,我将使用模态窗口模拟此弹出行为。谢谢你的帮助。 – 2013-02-17 13:34:48

0

你的请求流出来的角度的,所以它不会被认可,直到下一个$消化阶段(见程序如何处理的角度双向经脏匹配的绑定)。为了获得在你需要使用$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); 
    }); 
    }; 
+0

阅读你的回复我虽然“我是多么愚蠢!!”但实际上甚至在你的建议中问题仍然没有改变。为了确定我得到了你的意思,即使我的窃听代码正确地侦听并对'PlatformCtrl'控制器中的'handleBroadcast'事件作出反应(控制台显示'handleBroadcast(platform)'),你的解决方案也可能会保存我的一天。 )?顺便说一句,我会编辑我的文章,以反映你的回复。谢谢。 – 2013-02-15 12:39:05

0

难道你VisuCtrl尚未初始化,因为使用的是自定义路由? 当您导航到/visu/:idVisu时,它还是一样吗?

+0

我正在使用'ng-view'指令,所以我的VisuCtrl已经初始化了(至少我是这么认为的)。顺便说一句,谢谢你的尝试。 – 2013-02-15 12:07:24