63035

How share Service dynamic data between Controllers and Directives

Question:

I'd like to know what pattern to use, if I need my Service to share it's dynamic data between Controller, Directives, etc. The reason I mention dynamic, is because I'd like to load new data and this data needs to be available in any other Controller, Directive, etc. For example, if a Directive generates a UL LI, it would have to re-generate it if the data inside the Service has changed!

I've initially opened the following ( <a href="https://stackoverflow.com/questions/19126172/how-to-create-reset-method-in-service-that-return-promise" rel="nofollow">How to create reset() method in Service that return promise?</a> ) and someone pointed to me that I should use the Observer Pattern. Which I'm very grateful and I wrote this very quickly as a spike of what I need to do and comments would be extremely appreciated ( <a href="http://jsbin.com/epAMaP/1" rel="nofollow">http://jsbin.com/epAMaP/1</a> )

var MyApp = angular.module('MyApp', []); MyApp.config(function($locationProvider){ $locationProvider.hashPrefix('!'); }); MyApp.factory('MyService', function($timeout){ var data; var loadData = function(){ data = { foo: "bar", time: new Date() }; return data; }; return { refresh: function(){ loadData(); }, getData: function(){ return loadData(); } }; }); MyApp.controller('MyCtrl', function($scope,MyService,$timeout){ $scope.foo = "Service share data"; $scope.data = MyService.getData(); $scope.$on("eventFoo", function(){ console.log("Data has changed!"); console.log($scope.data); }); $timeout(function(){ MyService.refresh(); $scope.$apply(function(){ $scope.data = MyService.getData(); $scope.$emit("eventFoo"); }); }, 3000); }); MyApp.directive('myDirective', function(MyService,$timeout){ return { restrict: 'A', link: function(scope, elem, attrs){ scope.$on("eventFoo", function(){ console.log("Event foo triggered!"); scope.data = MyService.getData(); console.log(scope.data); }); } }; });

I think this would solve most of my problems but there's something that I need to remember. The data that I'll load comes from $http GET, so I think that I need to use at least a promise every time I need to update or load data, then trigger the right event.

My lack of experience with AngularJs drive me into question my thoughts, so any help or advice is extremely appreciated!

Thanks for looking!

Answer1:

I think I found a possible answer, using promise and the Observer Pattern (if this is correct and describes what I'm doing):

var MyApp = angular.module('MyApp', []); MyApp.config(function($locationProvider){ $locationProvider.hashPrefix('!'); }); MyApp.factory('MyService', function($q,$timeout,$rootScope){ var deferred; var data; var loadData = function(){ data = { foo: "bar" + Math.floor((Math.random()*100)+1), time: new Date() }; deferred.resolve(data); }; return { getPromise: function(){ deferred = $q.defer(); loadData(); return deferred.promise; }, getData: function(){ return data; } }; }); MyApp.controller('MyCtrl', function($scope,MyService,$timeout){ $scope.foo = "Service share data"; MyService.getPromise().then(function(data){ $scope.data = data; console.log("Initial data request:"); console.log($scope.data); $scope.$emit("eventFoo"); }); // then after awhile a user requests updated data $timeout(function(){ console.log("// then after awhile a user requests updated data"); $scope.$apply(function(){ MyService.getPromise().then(function(data){ $scope.data = MyService.getData(); $scope.$emit("eventFoo"); }); }); }, 3000); }); MyApp.directive('myDirective', function(MyService,$timeout){ return { restrict: 'A', link: function(scope, elem, attrs){ scope.$on("eventFoo", function(){ console.log("Event foo triggered!"); scope.data = MyService.getData(); console.log(scope.data); }); } }; });

You can find the code live at <a href="http://jsbin.com/ahiYiBu/1/" rel="nofollow">http://jsbin.com/ahiYiBu/1/</a>

Any tips or advice are extremely appreciate it,

Thanks a lot for your time :)

Answer2:

I don't know if this helps but I recently shared data between two controllers and a service by using

$rootScope.$broadcast to fire and $scope.$on to catch changes

as far as I can tell it is Angular's implementation of the observer pattern

Recommend

  • Angular route resolve calling a service
  • AngularJS. ng-include inside of ng-view infinitely loads content of ng-view
  • How to get URL segment in Angular JS?
  • spring autowire is not working returning null
  • How to replace a part of sections in ng-view?
  • log4j migration to log4j2
  • Is it a bad practice to rely on local objects get destructed in the reverse order of construction in
  • Feature Event Handler called multiple times for Farm level feature - sharepoint 2007
  • JAR doesn't work with Absolute Layout
  • ActionBar with appcompat library v7 (ava.lang.IllegalStateException: You need to use a Theme.AppComp
  • angularjs - ng-show doesn't update class when $interval triggers
  • docker-compose: connection refused between containers, but service accessible from host
  • Exception while trying to make Hazelcast cluster work with JCache compliant client
  • How to lookup value with multiple criteria in excel 2007 and newer
  • Accessing 3rd level of JSON with Angular ng-repeat
  • Slicing an SPA into several components and use AngularJS
  • to implement a spinner in angular2+
  • Android Database Error - getWriteableDatabase
  • C++ pointer value changes with static_cast
  • Authentication in Play! and RestEasy
  • Django simple Captcha “No module named fields” error
  • How do I exclude a dependency in provided scope when running in Maven test scope?
  • Do I need to reset a Perl hash index?
  • Is there a perl module to validate passwords stored in “{crypt}hashedpassword” “{ssha}hashedpassword
  • Use of this Javascript
  • Meteor helpers not available in Angular template
  • Invalid access key error using credentials redeemed from an amazon open id token
  • Circular dependency while pushing http interceptor
  • How to delete a row from a dynamic generate table using jquery?
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • using HTMLImports.whenReady not working in chrome
  • How does Linux kernel interrupt the application?
  • Authorize attributes not working in MVC 4
  • EntityFramework adding new object to nested object collection
  • Binding checkboxes to object values in AngularJs
  • UserPrincipal.Current returns apppool on IIS
  • git trying to push non-existent file … after clearing cache
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?