0

I'm developing some project where I use multiple modules

I have a kernel module and other modules that depend on kernel

angular.module('kernel', []);
...
angular.('process-manager', [ 'kernel', 'ui.router' ])
...
etc

I need to share some data across all modules and also broadcast some events across all modules.

For now in child modules I'm using $rootScope of kernel module that defined as a global in the $window object

.factory('$appScope', appScope)
...
appScope.$inject = ['$window', '$rootScope'];
function appScope($window, $rootScope: ng.IRootScopeService) {
    if (angular.isDefined($window.superScope) === false) {
        $window.superScope = $rootScope;
    }

    return $window.superScope;
}

Is there any better solution to do things like this?

EDIT kernel module bootstraped through ng-app and other modules bootstraped through angular.bootstrap();

Vlad Kosko
  • 84
  • 8

3 Answers3

2

I see you're using .factory()... in your code, and even though I'm not sure exactly how you use it, you might be on the right path.

Use services. Services are singletons that are meant to hold data that can be shared through injection across your app and even across modules. As for broadcasting events, you can call $broadcast on your $rootScope, or you can $watch changes on your services' data in all modules.

There's a better answer to a similar question here.

Here's an example:

angular.module('firstModule', []).service('MyService', function () {
  return {
    some: 'data'
  };
}).controller('someController', function ($scope, MyService) {
  $scope.$watch(function () {
    return MyService.some;
  }, function (some) {
    // This runs whenever the service's data changes
    console.log(some.data, 'logged in first module');
  }, true);
});

angular.module('secondModule', ['firstModule']) // <-- this makes the first module's service available for injection in the second module
  .controller('someController', function ($scope, MyService) {
    $scope.$watch(function () {
      return MyService.some;
    }, function (some) {
      // This runs whenever the service's data changes
      console.log(some.data, 'logged in second module');
    }, true);
  })

Cum grano salis

The service may be instantiated anew for every module, which may impede your ability to communicate across modules. Please fact-check me on this. In the meantime, local storage as suggested in Dennis Nerush's answer may be the better way to go. I have found https://github.com/gsklee/ngStorage to be a good complement for usage with Angular.

Community
  • 1
  • 1
Dennis Hackethal
  • 13,662
  • 12
  • 66
  • 115
  • I'm using factory instead of service. It's not a same? – Vlad Kosko Feb 20 '16 at 21:30
  • Not quite, but the difference is subtle, and it may work with factories as well. You may need to try it out. [Here](http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/)'s an explanation of the differences between services and factories (and providers). – Dennis Hackethal Feb 20 '16 at 21:32
  • I'll try to use services instead of factory and tell you about a result – Vlad Kosko Feb 20 '16 at 21:34
  • It shouldn't matter. What's important is that you can inject a service from one module into another and watch its data. That's how all modules stay informed about the data. – Dennis Hackethal Feb 20 '16 at 21:36
  • For now angular creates one factory for each module, so if I store some data to kernel's factory called 'MyFactory' this data will not appear in child module factory 'MyFactory'... – Vlad Kosko Feb 20 '16 at 21:44
  • Are you creating a second factory? You only need one and share it across modules. – Dennis Hackethal Feb 20 '16 at 21:46
  • No, I don't. I'm just watching events from factories. $scope.$on('SomeEvent', ...); – Vlad Kosko Feb 20 '16 at 21:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/104066/discussion-between-dchacke-and-vlad-kosko). – Dennis Hackethal Feb 20 '16 at 21:48
1

I suggest to use local storage to pass data between modules and keep the data consistent . Here is a great example

http://www.codediesel.com/javascript/sharing-messages-and-data-across-windows-using-localstorage/

Dennis Nerush
  • 5,473
  • 5
  • 25
  • 33
0

Register an event listner in the required modules as '$scope.$on('changedVariable', function (event, args){//do your thing in listning module});'

And in the module from where you need to braodast: $scope.$broadcast('changedVariable', { change: someValue}); And you are done, precisely! ;)

Sachin Siwach
  • 90
  • 1
  • 10
  • this will not work because I have a multiple bootstraped modules and each module has own $rootScope – Vlad Kosko Feb 20 '16 at 22:17
  • Works for me even with multiple modules... And that is only when you use $broadcast instead of $emit while going across modules – Sachin Siwach Feb 20 '16 at 22:23
  • I was tried it many times and it's not work. I can $broadcast event at 1 $rootScope but I can't $broadcast it on multiple $rootScopes – Vlad Kosko Feb 20 '16 at 22:25