Alexis F Alexis F - 26 days ago 7
AngularJS Question

AngularJS: The "best" way to bind a Factory variable to a $scope or a directive?

I'm working on a new AngularJS project, and encountered a problem that annoys me more than it actually should...

I have an Angular Service containing data I need to access from multiple views and controllers, and updated by another Service which is receiving continuous data from a server, via SocketIO.

Something like :

angular.module('Foo', [])

.factory('DataContainer', function(){
var data = [];
var o = {};
o.all = function() {
return data;
};
o.add = function(item){
data.push(item);
};
return o;
})

.factory('DataReceiver', function(DataContainer){
var o = {}
o.init = function(){
socket = io.connect()
.on('data', function(item){
DataContainer.add(item);
};
};
return o;
})

.directive('dataList', function(DataContainer) {
return {
restrict: 'E',
template: '<ul><li ng-repeat="item in data">{{item}}</li></ul>',
replace: true,
link: function(scope) {
scope.data = DataContainer.all();
}
};
});


Problem is that "dataList" does update when DataContainer.add() is call from the parent's controller, but does not when DataContainer.data is updated by the DataReceiver service (as the $scope itself does not update).

I tried many things, including things like :

$scope.data = DataContainer;
.....
ng-repeat="item in data.all() track by $index"


thinking it could solve my problem. But it didn't.

I'm now considering using $rootScope, or $watch combined with a $scope.apply() to pass and update my data, but it sounds pretty heavy, and I'm not sure it's the proper way to go...

What am I doing wrong ? Any proper way to bind a Service variable to a controller $scope or a directive ?
Thanks for the help !

Answer

try this

.factory('DataReceiver', function(DataContainer, $rootScope){
    var o = {}
    o.init = function(){
         socket = io.connect()
         .on('data', function(item){
              DataContainer.add(item);
              $rootScope.$apply()
         };
    };
   return o;
})