0

预赛

我正在使用 angularjs 开发一个网络应用程序。在某些时候,我的主控制器连接到一个连续发送数据的 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.$ro​​otScope.Scope#$on 侦听器。

由于给定应用程序中的所有范围都继承自$rootScope,因此我不明白为什么每次广播新数据时都不会启动$on函数 in 。VisuCtrl

4

3 回答 3

2

我认为当你打开一个新的浏览器窗口时,你正在启动一个新的 AngularJS 实例。这样,两个控制器不可能通过服务进行通信。

如果您在范围通信方面遇到问题,您可以注入 $rootScope 并查看是否所有应该通信的范围都实际实例化。

function VisuCtrl($scope, $routeParams, sharedService, $rootscope) {
    console.log($rootScope);
}
于 2013-02-17T11:59:50.443 回答
0

您的请求流来自 angular,因此直到下一个 $digest 阶段才会被识别(请参阅 angular 如何通过脏匹配处理双向绑定)。要进入角度世界,您需要使用$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);
     });
  };
于 2013-02-15T11:40:11.470 回答
0

可能是您的 VisuCtrl 尚未初始化,因为您使用的是自定义路由?当您导航到 时,它是否仍然相同/visu/:idVisu

于 2013-02-15T11:57:13.297 回答