Angularjs provider with different configurations in different modules

I would like to know if there is a way to make the vendor configuration unique not for the whole application, but only through the module that configures it.

For example, I have a "core" module that contains a vendor definition. Then I have modules "module1" and "module2" that use the provider, but need to configure it in a specific way for a particular module.

What happens to me is that the configuration done in the last module overrides the configuration done in all other modules that use the provider in the application.

I made this simple plunker to illustrate this:

var app = angular.module('app', ['module1','module2']);

angular.module('core',[])

.provider('movie', function () {
  var version;
  return {
    setVersion: function (value) {
      version = value;
    },
    $get: function () {
      return {
          title: 'The Matrix' + ' ' + version
      }
    }
  }
});

angular.module('module1',['core'])

.config(function (movieProvider) {
  movieProvider.setVersion('Reloaded');
})

.controller('ctrl1', function ($scope,movie) {
  $scope.title = movie.title;
  $scope.module = 'module1';
});


angular.module('module2',['core'])

.config(function (movieProvider) {
  movieProvider.setVersion('Revolutions');
})

.controller('ctrl2', function ($scope,movie) {
  $scope.title = movie.title;
  $scope.module = 'module2';
});

      

http://plnkr.co/edit/BI5nhmcdgzQZfZo56Koh?p=preview

+3


source to share


1 answer


Theory and other useless shit

In angular providers, $ get is meant to return a single instance of the provided functionality; $ get () is re-executed on every instance of the provider (like a factory). A function or object that provides a provider definition is created only once (for example, a service).

So, to get factory-like properties from your provider, you want to keep the instance-specific properties within $ get; and get the service properties that depend on $ get.

This may seem a bit limited or roundabout at first, but it allows you to combine scoped with scoped and globally scoped properties in really nifty ways.

Your problem in particular

For your specific problem, if we just move var version

in $get

, we suddenly get the factory-like behavior you were looking for:

.provider('movie', function () {
  return {
    $get: function () {
      var version;

      var obj = {
          title: function() { return 'The Matrix' + ' ' + version; },
          setVersion: function (value) {
            version = value;
          }
      };

      return obj;
    }
  }
});

      

( http://plnkr.co/edit/0m9qKzNuhCOOXTbrCQ1T?p=preview )

Changing the scope (along with changing the name to a function variable instead of a string created statically when obj is created) gets the desired result:



This is module module1

Title: The Matrix Reloaded

This is module module2

Title: The Matrix Revolutions

      

It's basically like an ATM factory.

Where providers really excel

To go into a more common provider use case (where we want to combine the global and per instance), let's say we wanted the API provider that it uses to be able to use one of several APIs in different countries, applications, but only one API for each application. We want our provider to look something like this:

.provider('movie', function () {
  var imdbEndpoint;

  return {
    setApiEndpoint: function(newImdbEndpoint) {
      imdbEndpoint = newImdbEndpoint;
    },
    $get: function () {
      var version;

      var obj = {
          title: function() { return imdbEndpoint + ' says the The Matrix version is ' + ' ' + version; },
          setVersion: function (value) {
            version = value;
          }
      };

      return obj;
    }
  }
});

      

( http://plnkr.co/edit/ZoSgQDpNdX8MOmet7xzM?p=preview )

Conclusion: This is the module module1

Title: api.imdb.com says the The Matrix version is Reloaded

This is module module2

Title: api.imdb.com says the The Matrix version is Revolutions

      

So now our API endpoint url is globally (or on a per app basis), but we can link to any movie we want without getting confused about which layer of the Neo matrix is ​​on - because it is really, isn't it?

+4


source







All Articles