2014-09-01 77 views
2

我目前正在嘗試使用$ rootScope。$廣播方法來觸發我的angularjs服務中的事件。爲此,我創建了一個負責觸發事件的服務,並設置了不同的服務來提取事件。重要的是,提取事件的服務應該獨立於應用程序的其餘部分,這就是爲什麼我採用共享服務方法。角度廣播不與獨立服務

我的廣播服務(共享),它被調用我的應用程序觸發事件:

angular.module('myModule') 
    .factory('phaseListener', ['$log', '$rootScope', function ($log, $rootScope) { 

    var phaseListener= {}; 

    phaseListener.broadcastPhase = function(phase) { 
     $rootScope.$broadcast('test'); 
    }; 

    return phaseListener; 
}]); 

以下服務「TestService的」我聽着這個事件,但它不會被觸發。我從另一個服務調用broadcastPhase()方法,並觸發該方法。

angular.module('myModule') 
    .factory('testService', [ '$rootScope', '$scope', '$log', 'phaseListener', 
    function ($rootScope, $scope, $log, phaseListener) { 

    $rootScope.$on('test', function() { 
     $log.debug('This works'); 
    }); 

    }]); 

如果我正在偵聽當前加載的控制器中的事件,它會起作用。但我的目標是觸發當前未加載的其他控制器/服務中的事件(至少在頁面上不可見)。通過將phaseListener定義爲testService的依賴項,我希望它能夠在後臺加載。

如何通過定義依賴關係來實現此通信?我無法將testService定義爲phaseListener的依賴項。 testService是一個模塊的例子,它可以單獨編碼,並且可以很容易地與我的應用程序集成。

依賴關係: 服務1 => SharedService < =服務2

消息: 服務1 => SharedService =>服務2

+0

由於這些控制器/服務未加載,因此'$ on'偵聽器也未加載。所以這將永遠不會工作。你必須確保服務或控制器功能已經運行,你希望他們'聽'這些事件。 – RoryKoehein 2014-09-01 18:06:30

+0

如果我無法在我的phaseListener服務中添加依賴項,我該如何做到最好? – jimmy 2014-09-01 19:00:22

+0

就個人而言,我會使用UI路由器來改變應用程序的'狀態',一旦某個事件被觸發。狀態可以與控制器/服務/模板結合使用。 https://github.com/angular-ui/ui-router – RoryKoehein 2014-09-01 19:03:54

回答

1

我發現了一個很好的方式來實現我所期待的。也許有人可以使用它:因爲我不知道在啓動時需要監聽廣播事件的所有服務,所以我不能像通常那樣添加依賴項。相反,我可以通過「$ injector.get('serviceName');」在運行時手動注入服務。在此之後,服務被注入並且任何後續廣播也將到達新注入的服務。

1

服務是單身,因此,儘管這是真的,他們必須要加載爲他們工作,一旦他們在那裏沒有太多的成本讓他們實例化。這不像你最終會有12份。我每天都會使用這種模式,並且我發現最好只製作app.js的所有服務依賴項。在我的主要「運行」處理程序中,我注入了所有計劃使用的主要服務。這保證了它們可用,並且在其他人開始做任何可能發出事件的事情之前加載它們。加載它們並不需要太多內存,並且在事件實際被觸發之前沒有任何工作量。幾乎沒有理由不這樣做 - 服務是全局實體,而延遲加載它們並沒有多大價值。

angular.module('myApp', ['myService1', 'myService2', 'myService3']) 
.run(['$rootScope', 'myService1', 'myService2', 'myService3', function() { 
    // NOTE: You may or may not actually need to do anything here. But by asking the 
    // injector for each service you can guarantee that they're loaded when the app 
    // starts. That lets them set up any listeners necessary for them to function. 
    // Note that the order in which you ask for them here will determine the order in 
    // which they're instantiated! 
}); 

你也可以考慮使用'服務'而不是'工廠'。你沒有利用兩者之間的差異,所以工廠不會給你帶來任何好處。服務基本上只是工廠「通常需要這種方式...」機制的簡寫形式,如果您使用服務,則會保存兩行代碼(var定義和return語句) :

angular.module('myModule') 
    .service('phaseListener', ['$log', '$rootScope', function ($log, $rootScope) { 
     this.broadcastPhase = function(phase) { 
      $rootScope.$broadcast('test'); 
     }; 
    }]); 

如果你願意,你仍然可以在服務中定義scope-locals - 但它是可選的。

我不會這樣做的唯一時間是,如果有很多他們......但在這種情況下,我會質疑該應用程序的體系結構。我正在構建一個具有6個月開發週期的非常複雜的應用程序,到目前爲止我們只有9個服務。這只是一個軼事,但我仍然很驚訝地發現有人爲其中30多個應用程序提供了一個好的例子。通常在那個時候,你想重新考慮'管理者'模式實際上爲你做了什麼,這就是工廠和提供者實際上有用的地方。在那裏你可以擁有核心服務來處理所有的pub/sub工作,並管理其中的智能對象,這些智能對象根據應用程序的狀態執行各種特定的功能。

一個很好的例子就是模態窗口管理器。你可能有幾種類型的模態都有不同的行爲。您可以創建一個基於參數生成每種類型的主服務,而不是創建三個服務。然後,您可以區分燈箱和「純」模式,但仍然通過單一服務管理它們。

+0

感謝您的詳細解釋。這證實了我所害怕的。我想我必須在啓動時以某種方式連接服務。我希望能夠創建某種模塊/插件類型的體系結構,您可以編寫自己的服務/控制器並將其插入基本應用程序,而無需更改現有應用程序中的任何內容。看來我將不得不引入一些虛擬服務來處理所有的依賴關係。也感謝工廠/服務提示 - 我肯定會看看這個。 – jimmy 2014-09-02 04:39:39