2013-02-15 110 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

相關問題