ajmajmajma
ajmajmajma

Reputation: 14216

Angular, use a service or factory?

I am trying to set up a middle ground between modules to get a custom url so that the user may save (copy the url) the state and share it with other users (or return to it). I am trying to build a simple working copy, then my goal is to make it as polymorphic as possible.

I have a basic working copy right now using a url object to store some variables (in the url object right now), which are then read in the controllers on load to change to the desired state. For example, the very top of my first controller is

 $scope.test = $location.search().test;

so whatever test= in the url, it will set to $scope.test (these control my state). I have everything broken out into individual modules right now, so my initial method of getting the modules to speak is setting a function like this (found elsewhere on stack)

function persistMod($scope, $window) {

$scope.$watch(function (){
  return $window.test;
}, function(v) {
if(v == undefined ){}else{
  if($scope.test !== v) {
     $scope.test = v;
  }
}
});

$scope.$watch('test', function(v) {
  if($window.test !== v) {
     $window.test = v;
  }
});

$scope.$watch(function (){
   return $window.test2;
}, function(v) {
if(v == undefined ){}else{
  if($scope.test2 !== v) {
     $scope.test2 = v;
  }
}
});

 $scope.$watch('test2', function(v) {
  if($window.test2 !== v) {
     $window.test2 = v;
  }
});
}

And in the controllers I just call

persistMod($scope, $window);

The purpose of this is to let them keep track of each other separately so when the url is updated - each module can keep track of the other ones current state so there is no confusion. So I can call

$location.search({mod1: $scope.test, mod2: $scope.test2});

When the state changes in each and it will stay the same.

So the problem here is - I would like to turn this into a service I can inject into both modules as an in between to keep track of this for me and change the url accordingly. So I'm wondering is this more of a factory or a service's job.

I want to :

-keep track of how many states change (lets say there can be a min of 2 and a max of 15) and change the url accordingly

-be able to send the new url individually for each module and have it update the url string with kind of a post to the service like myService.urlChange("newurlvariable");

So the factory/service would have to keep track of how many modules are using it and change accordingly. This is still new to me so I could use some guidance, I've done a bunch of digging around and feel stuck right now. Any insight is more than welcome. Thanks for reading!

Upvotes: 2

Views: 390

Answers (2)

ribsies
ribsies

Reputation: 1218

So you definitely want a factory for this. But you will need to rewrite most of this to do what you want.

It's important to think of factories as a singleton, almost like global functions and variables. You could have a factory like this...

app.factory('PersistMod', [
  function() {
    var service = {};

    service.url;
    service.addItem = function(item) {
      service.url = service.url + item;
    }

    service.getUrl = function() {
      return service.url;
    }

    return service;
  }])

I won't write our the whole thing but hopefully this will give you an idea on how to set it up.

Once this is setup you can inject this factory into your controller and then call the functions or get the variables. For example

PersistMod.addItem('something');
var currentUrlString = PersistMod.getUrl;
console.log(currentUrlString) // 'something'

Hopefully that helps.

Upvotes: 1

jlowcs
jlowcs

Reputation: 1933

Something like that?

angular.module(...).factory('persistMod', function ($window) {
    return function persistMod($scope, name) {
        //watch $window[name]
        //watch $scope[name]
    }
});

[...]

angular.module(...).controller('MyCtrl', function($scope, persistMod) {
    persistMod($scope, 'test');
    persistMod($scope, 'test2');
});

Also, why not simplify this:

if($window.test !== v) {
    $window.test = v;
}

...with this:

$window.test = v;

No need to test before assigning.

Upvotes: 1

Related Questions