AngularJS sharing data between factory & controlle

2019-07-15 09:09发布

问题:

I have an angularjs app that has several modules. The main modules looks something like:

var app = angular.module('mainMod', ['apiService']);
app.controller('MainCtrl', function (Socket) {
    $scope.objects = {};
    // do something with $scope.objects, etc.
});

And then I have;

var apiService = angular.module('apiService', ['ngResource']); // etc

and;

apiService.factory('Socket', ['$rootScope', function ($rootScope) {
    // create a websocket and listen for stuff
    // if something happens, update 'objects' in $rootScope
}]);

The thing is, I see that the service Socket has been injected in MainCtrl, but inside the Socket service, I can not access $rootScope.objects. I do understand that factories have no scopes of their own, but since its injected into MainCtrl, shouldn't the rootscope refer to the scope of the MainCtrl?

There is a workaround using events, but I'm not too keen on that. I have tried it with success but I'd prefer a solution where this just works.

回答1:

You forgot to inject the $scope into your controller itself:

app.controller('MainCtrl', function ($scope, Socket) {
    $scope.objects = {};
   // do something with $scope.objects, etc.
});

But this still won´t help you to access the "objects" of this controller via the rootScope, since $scope inherhits $rootScope, but not the other way around - so whatever you define on the $scope wont be propagated to the $rootScope.

What you CAN do however is to link the $scope.objects with a varibale inside your factory itself, so something like this:

var app = angular.module('mainMod', ['apiService']);
app.controller('MainCtrl', function (Socket) {
   $scope.objects = Socket.objects = {};
    // do something with $scope.objects, etc.
});

And in your Socket-Factory:

apiService.factory('Socket', ['$rootScope', function ($rootScope) {
    return {
       objects : {}
   }
}]);

Just be careful then to not overwrite the $scope.objects directly, since it will break the reference again.