3

I've seen some examples where methods are added to the AngularJS controller as mixins. For example:

(function () {
  var app = angular.module('angularjs-starter', []);

  var ParentCtrl = function ($scope, $location) {
    $scope.path = function () {
      return $location.absUrl();
    };
  };

  app.controller('ChildCtrl', function($scope, $injector) {
    $injector.invoke(ParentCtrl, this, {$scope: $scope});
    $scope.url = $scope.path();
  });
})();

I want to be able to add new methods as a 'mixin' to a factory. How can I do that? It's not possible to pass $scope into a factory.

For example, the following doesn't work:

var serv = angular.module('myModule', [])

serv.factory('myService', ['$scope', '$injector', function ($scope, $injector) {
...
George Hernando
  • 2,550
  • 7
  • 41
  • 61
  • You shouldn't have to pass scope into factory. Is that what's preventing you from what you're trying to do? – Marc Kline May 30 '14 at 00:34
  • I'm looking for a way to do mixins to add factory methods. All examples of mixins that I've come up with are for controllers. In the examples I've found for controllers, $scope is always used. – George Hernando May 30 '14 at 01:32
  • Controllers usually have scope injected into them, while factories do not. You can inject rootScope into factories, but generally that's bad practice. – Marc Kline May 30 '14 at 01:35
  • I want to be able to add some methods to those of a factory or service. Is there some other way that I can do that? – George Hernando May 30 '14 at 01:59
  • You can inject a factory into virtually any Angular component and decorate it with additional methods and properties. There are other ways to extend them as well. Please update your question with more specifics about your goals if you'd like a more detailed answer. – Marc Kline May 30 '14 at 06:01

1 Answers1

5

You can use angular.extend to achieve this, which copies all of the source object's properties into the destination object.

For example:

(function () {
  var app = angular.module('angularjs-starter', []);

  app.factory('CalculatorFactory', function() {
    return {
      add: function(arg1, arg2) {
        return arg1 + arg2;
      }
    }
  });

  app.controller('MainCtrl', function($scope, CalculatorFactory) {
    angular.extend($scope, CalculatorFactory);

    // $scope now has the `add() fn`
    var result = $scope.add(1, 2);
  });

})();
Tom Spencer
  • 7,816
  • 4
  • 54
  • 50