Injecting service/factory to directive

angularjs, angularjs-directive

Solution

That's not possible that way. The best you can do is bind the directive scope to a function of its parent scope that returns an instance of your service:

app.directive('changeIt', function(){
  return {
    restrict: 'CA',
    scope: { getDataFn : '&' },
    link: function (scope) {
      scope.name = getDataFn().name;
    }
  }
});     

and then in your view:

<div class='change-it' get-data-fn='getMyData()'></div>
<div class='change-it' get-data-fn='getYourData()'></div>

Finally, you need to add `getMyData()` and `getYourData()` to the parent scope:

app.controller('Ctrl', function($scope, myData, yourData) {
  $scope.getMyData = function() {
    return myData;
  };

  $scope.getYourData = function() {
    return yourData; 
  };
});

Plunker script here.

I can think of another approach, though: you could create an abstract factory and inject it into the directive, and then pass a parameter to the directive so it could tell the abstract factory to create the correct service. Something like this:

app.service('dataFactory', function(myData, yourData) {
  this.create = function(type) {
    if (type === 'myData')
      return myData;
    else if (type === 'yourData')
      return yourData;
  };
});

app.directive('changeIt', function(dataFactory){
  return {
    restrict: 'CA',
    scope: true ,
    link: function (scope, element, attrs) {
      scope.name = dataFactory.create(attrs.type).name;
    }
  }
});

And now you need to pass the type to the directive:

<div class='change-it' type="myData"></div>
<div class='change-it' type="yourData"></div>

Plunker here.

Problem

I have two/more services with same signature. Can I dynamically inject then into the directive? something like below ``` var app = angular.module('app',[]); app.factory('myData', function(){ return { name : "myName", id : 1, create: function(){ //do something } } }); app.factory('yourData', function(){ return { name : "yourName", id : 1, create: function(){ //do something } } }); app.directive('changeIt',function($compile){ return { restrict: 'CA', scope:{ data : '=' //or some oether syntax? }, link: function (scope, element, attrs) { scope.name = data.name; } } }); ``` Then I should be able to use the directive as below ``` <div class='change-it' data='myData'>{{name}}</div> <div class='change-it' data='yourData'>{{name}}</div> ``` I would be adding more services with the same signature and I should be able to use the directive without changing, is it possible?

Original source