2017-08-15 51 views
0

我正在學習RxJS,並試圖在我的一個現有應用程序中實現它。我想要做的第一件事是刪除rootscope.broadcast/emit方法並將其替換爲BehaviorSubjects。如果這些事件訂閱到控制器內,這可以正常工作。但是,如果我嘗試訂閱服務中的這些事件,他們絕不會開火。我可以將完全相同的訂閱移動到組件/控制器/等等,它可以正常工作。AngularJS服務中的RxJS

這是有理由還是應該我能夠做到這一點,我只是做錯了什麼?

UPDATE 1

我有一個事件服務維持的事件在應用的,像這樣的頂部運行:

(function() { 
"use strict"; 
angular.module("app.common").service("eventService", EventService); 
function EventService($window) { 
"ngInject"; 

var defaultBehaviorSubjectValue = null; 

var service = { 
    activate: activate, 
    onLogin: new Rx.BehaviorSubject(defaultBehaviorSubjectValue),      //onnext by authService.login 
    onLogout: new Rx.BehaviorSubject(defaultBehaviorSubjectValue),     //onnext by authService.logout 
    isOnline: new Rx.BehaviorSubject(defaultBehaviorSubjectValue)     //onnext by authService.logout   
}; 

return service; 

function activate() { 
    service.onLogin.subscribe(function (userData) { 
    console.info("user logged in"); 
    }); 

    service.onLogout.subscribe(function (userData) { 
    console.info("Logging user out"); 
    dispose(); 
    }); 

    $window.addEventListener("offline", function() { 
    console.info("Lost internet connection, going offline"); 
    service.isOnline.onNext(false); 
    }, false); 

    $window.addEventListener("online", function() { 
    console.info("Regained internet connection, going online"); 
    service.isOnline.onNext(true); 
    }, false); 
} 

function dispose() { 
    angular.forEach(service, function (event, index) { 
    if (service && service[event] && service[event].isDisposed === false) { 
     service[event](); 
    } 
    }); 
} 

} })();

我有一個服務正在等待onLogin事件觸發。該代碼類似於:

(function() { 
angular.module("app.data").service("offlineProjectDataService", OfflineProjectDataService); 

function OfflineProjectDataService(definitions, metaDataService, userService, eventService) { 
    "ngInject"; 

    var onLoginSubscription = eventService.onLogin.subscribe(function (isLoaded) { 
     if (isLoaded) { 
      activate(); 
     } 
    }); 

    var service = { 
     activate: activate 
    } 

    return service; 

    function activate(){ 
     //..some stuff 
    } 
} 

})();

我遇到的問題是onLogin事件沒有觸發,所以我的激活方法沒有被調用。如果我將這個完全相同的訂閱線移動到我的應用中的其他控制器,它會觸發。所以我不認爲語法有什麼問題。

除非我在這裏丟失了某些對某人來說可能很痛苦的東西。

+1

服務需要被調用,然後你提到的所有內容都會觸發。不僅僅是爲了注射他們自動工作,你需要調用任何服務的方法。 –

回答

0

使用RxJS在服務

構建服務與RxJS Extensions for Angular

<script src="//unpkg.com/angular/angular.js"></script> 
<script src="//unpkg.com/rx/dist/rx.all.js"></script> 
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script> 
var app = angular.module('myApp', ['rx']); 

app.factory("DataService", function(rx) { 
    var subject = new rx.Subject(); 
    var data = "Initial"; 

    return { 
     set: function set(d){ 
     data = d; 
     subject.onNext(d); 
     }, 
     get: function get() { 
     return data; 
     }, 
     subscribe: function (o) { 
     return subject.subscribe(o); 
     } 
    }; 
}); 

然後只需訂閱變化。

app.controller('displayCtrl', function(DataService) { 
    var $ctrl = this; 

    $ctrl.data = DataService.get(); 
    var subscription = DataService.subscribe(function onNext(d) { 
     $ctrl.data = d; 
    }); 

    this.$onDestroy = function() { 
     subscription.dispose(); 
    }; 
}); 

客戶可以訂閱與變化,並DataService.subscribe生產者可以用DataService.set推變化。

DEMO on PLNKR

+0

我相信我的實際問題是上面耶穌卡拉斯科所說的,但我認爲你所展示的實際上是我應該實施的解決方案。我會開始實施它,而不是我這樣做。 – JakeHova