2013-02-15 4 views
0

ПРЕДВАРИТЕЛЬНЫЕСвязь между контроллерами невозможно

Я занимаюсь разработкой веб-приложений с использованием angularjs. В какой-то момент мой главный контроллер подключается к веб-службе, которая непрерывно отправляет данные. Чтобы захватить и обработать поток, я использую (http://ajaxpatterns.org/HTTP_Streaming). Все работает как шарм. Я хотел бы поделиться этими потоковыми данными с другим контроллером, который будет обрабатывать и отображать их через библиотеку jquery chart (еще не решил, какой из них я буду использовать, но это выходит за рамки этого вопроса). Чтобы поделиться этими данными, я следил за этим 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]; 
    }); 


} 

Injection:

PlatformCtrl.$inject = ['$scope','$http','$q','$routeParams','mySharedService']; 
VisuCtrl.$inject = ['$scope','$routeParams','mySharedService']; 

ЗАДАЧИ

При выполнении этого кода, он выглядит, как только контроллер PlatformCtrl прослушивает handleBroadcast события. В самом деле, глядя на консоль, все, что отображается, только handleBroadcast (platform) каждый раз, когда поступают новые данные. Я очень удивлен, потому что я прочитал в официальной документации, что $broadcast функция

отправляет имя события вниз для всех дочерних областей (и их детей) уведомлениями зарегистрированных нг. $ RootScope.Scope # $ на слушателях ,

Поскольку все прицелы в данном приложении наследует от $rootScope, я не понимаю, почему $on функция VisuCtrl не запускается каждый раз, когда новые данные транслируются.

+0

Значит, вы используете PlatformCtrl для/home и VisuCtrl at/visu /: idVisu, но они все еще работают в одно и то же время? Это несколько сбивает с толку :) Не могли бы вы помочь мне разобраться? –

+0

@Flek. Точно так, идея состоит в том, чтобы открыть всплывающее окно для отображения потоковых данных с помощью VisuCtrl. В то же время PlatformCtrl будет работать. –

+0

Но два контроллера действительно работают в одном и том же угловом экземпляре? Я спрашиваю, потому что, если я получу это правильно, вы используете window.open, поэтому вы открываете новое окно браузера, не так ли? –

ответ

2

Я думаю, что когда вы открываете новое окно браузера, вы запускаете новый экземпляр AngularJS. Таким образом, невозможно, чтобы два контроллера могли общаться через службу.

Если у вас возникли проблемы с обменом областями, вы можете ввести $ rootScope и посмотреть, действительно ли задействованы все области, которые должны взаимодействовать.

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

Вы правы, и на самом деле я пришел к такому же выводу. Когда visuCtrl находится на той же странице, что и PlatformCtrl, эти два контроллера могут взаимодействовать. После некоторого googling, довольно сложно создать приложение браузера с несколькими браузерами в javascript. Следовательно, я смоделирую это всплывающее поведение, используя модальное окно. Спасибо за вашу помощь. –

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); 
    }); 
    }; 
+0

Чтение вашего ответа. Хотя «Как я глуп!» но на самом деле даже с вашим предложением проблема остается неизменной. Чтобы быть уверенным, что я понял, что вы имели в виду, было бы возможно, что ваше решение сохраняет мой день, даже если мой прослушиваемый код правильно прослушивает и реагирует на событие 'handleBroadcast' в контроллере' PlatformCtrl' (консоль отображает 'handleBroadcast (platform)' ')? Btw, я отредактирую свой пост, чтобы отразить ваш ответ. Благодарю. –

0

Может быть, что ваш VisuCtrl еще не инициализированы, так как вы используете пользовательские маршрутизации? Разве все равно, когда вы переходите на /visu/:idVisu?

+0

Я использую директиву 'ng-view', поэтому мой VisuCtrl был инициализирован (по крайней мере, я так думаю). Кстати, спасибо за вашу попытку. –

Смежные вопросы