angularjsangular-ui-routerangular-dependency-injection

Angularjs different dependency injection for factories inside controller


Say I have multiple factories and these factories have same functions and variables inside. For example,

var app = angular.module('app', []);
app.factory('employerFactory', function () {
        return {
            firstName: 'Kristoffer',
            lastName: 'Karlsson',
        };
    });
app.factory('employeeFactory', function () {
        return {
            firstName: 'Alice',
            lastName: 'Guo',
        };
    });

Now I have a controller like this:

app.controller('MyController', function($scope, myFactory) {
    $scope.firstName = myFactory.firstName;
    $scope.lastName = myFactory.lastName; 
 });

My question is that how to initiate two controllers, one is passed in employerFactory as dependency and the other is employeeFactory. I know a routerProvider could help to route different controllers for different url. Can I manipulate on it to pass different factories into controller? something like

$routeProvider.
  when('/a', {
    templateUrl: 'test.html',
    controller: 'MyController' // should get passed factory 'employerFactory'
  }).
  when('/b', {
    templateUrl: 'test.html',
    controller: 'MyController' // should get passed factory 'employeeFactory'
});

Solution

  • Just use a service as an extra layer to deal with the switching logic, inject both factories in it, then create methods to handle common functionality:

    app.service('FactoryService', function($scope, employerFactory, employeeFactory) {
       var _mode = 0;
       var _factories = [employerFactory, employeeFactory];
       return {
          setMode: function(mode) {
             _mode = mode % (_factories.length - 1);// possibly 0 | 1 in this case, but inject as many factories as you wish
          },
          getFirstName: function() {
             return _factories[_mode].firstName;
          },
          getLastName: function() {
             return _factories[_mode].lastName;
          }
       }
     });
    

    Finally inject it into your controller, and call its methods

    app.controller('MyController', function($scope, FactoryService) {
    
        // select the first factory (employerFactory)
        FactoryService.setMode(0);
        $scope.firstName = FactoryService.getFirstName();
        $scope.lastName = FactoryService.getLastName(); 
        console.log( $scope.firstName, $scope.lastName); 
    
        // select the second factory (employeeFactory)
        FactoryService.setMode(1);
        $scope.firstName = FactoryService.getFirstName();
        $scope.lastName = FactoryService.getLastName(); 
        console.log( $scope.firstName, $scope.lastName); 
     });
    

    The switching logic can be based on whatever you want, this is just an example of how it could work.