2014-06-13 51 views
2

我想將數據從一個控制器發送到另一個控制器。其實我已經遵循了這一link

我的第一個控制器是這樣的:

class ProductCtrl 

constructor: ($scope, @$log, @$location, @$timeout, @ProductService) -> 

    $scope.go = (path) => 
     $scope.$emit('handleEmit', @getAllProducts()) 
     $location.path path 

第二個:

class UpdateProductCtrl 

constructor: ($scope, @$log, @$routeParams) -> 
    $scope.$on('handleBroadcast', (event, data) -> 
     console.log(data) 
    ) 

App.coffee:

app = angular.module('myApp', dependencies) 
app.run ($rootScope, editableOptions) ->  
    $rootScope.$on 'handleEmit', (event, args) -> 
     $rootScope.$broadcast 'handleBroadcast', args 

內部應用咖啡$ rootScope 。$ on'handleEmit'在我調用$ scope時不會觸發。$ emit('handleEmit',@getAll產品())在ProductCtrl中。請幫助我做錯了什麼。

回答

3

從我對其他答案的評論,我明白,2控制器是在2個不同的路線。使用事件傳遞數據不會這樣工作,因爲當第一個控制器發出事件時,第二個控制器尚未註冊其偵聽器。

所以,你需要另一種方式來在路由之間傳遞數據。你可以使用一個服務來做到這一點,但由於服務是全局對象,你需要對你傳遞的數據進行某種類型的範圍和維護,以便不累積垃圾或使用陳舊的數據。

您可以創建像個具有以下屬性的一個全球性的「存儲」對象服務:

  • 它可以接受用於下一路由數據
  • 它可以提供適用於當前的路線
  • 數據

該服務在內部維護兩個「桶」。在nextRouteBucket上執行所有put操作,並且在currentRouteBucket上執行所有get操作。當角色的路由器廣播$routeChangeStart事件時,服務會切換存儲桶並清理。

class NavScope 
    constructor: ($rootScope) -> 
    @currentRouteBucket = {} 
    @nextRouteBucket = {} 

    $rootScope.$on '$routeChangeStart',() => 
     @currentRouteBucket = @nextRouteBucket 
     @nextRouteBucket = {} 

    put: (name, data) -> 
    @nextRouteBucket[name] = data 

    get: (name) -> 
    @currentRouteBucket[name] 

的下一個路由上的控制器可以簡單地調用navScope.get 'someKey'從以前的路線檢索數據或在路線resolve對象檢索它們(見plunker)。

請記住,這只是一個原型,並且可能會出現某些情況,例如用戶使用瀏覽器「後退」和「前進」導航或路由失敗時。您始終必須將相關的ID放在URL上,這樣如果您在navScope上找不到數據,請從服務器檢索它們。

看看猛擊here

+0

「錯誤:[$ injector:unpr]未知的提供程序:NavScopeProvider < - NavScope」錯誤顯示在我的控制檯上。我在這裏錯過了什麼? – nAkhmedov

+0

你有沒有在你的「Route2Ctrl」中遇到以下錯誤「Error:[$ injector:unpr] Unknown provider:messageProvider < - message」? – nAkhmedov

+0

它工作得很好! :)太謝謝你了 – nAkhmedov

2

我已將這coffeescript plunker從您的代碼中刪除,它似乎工作正常。沒有CoffeeScript的特性,無論如何。

檢查run回調確實運行,或檢查事件名稱中的拼寫錯誤。

但是,一個建議是:無論何時需要控制器之間的「消息總線」通信方式,都傾向於釋放僅在$rootScope級別生存的事件。廣播事件向下有$rootScope可能是昂貴的,因爲它必須遍歷整個範圍層次結構。想象一下你的頁面某處ng-repeat創建500個子範圍的懲罰。我知道,它是程序性的,whiles和ifs,但是 - 無論如何 - 它是不需要運行的代碼。

你可以簡單的寫:

app = angular.module('plunker', []) 

class ProductCtrl 
    constructor: ($scope, $rootScope) -> 
    $scope.go =() -> 
     $rootScope.$emit 'MyEvent', {message: 'Hello!'} 

app.controller 'ProductCtrl', ProductCtrl 

class UpdateProductCtrl 
    constructor: ($scope, $rootScope) -> 
    unsubscribe = $rootScope.$on 'MyEvent', (event, data) -> 
     $scope.message = data.message 
    $scope.$on '$destroy', unsubscribe 

app.controller 'UpdateProductCtrl', UpdateProductCtrl 

這樣,是不是需要在所有run回調。 檢查出here

+0

確定它工作正常。我認爲問題在於我會打開另一個頁面,這就是爲什麼第一個控制器在形象上消失的原因。 – nAkhmedov