控制器之间无法通信

时间:2013-02-15 10:53:42

标签: angularjs

预赛

我正在使用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功能。

3 个答案:

答案 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时是否仍然相同?