Albireo
Albireo

Reputation: 11085

Have AngularJS inject dependencies into objects like it already does for controllers

I'm using AngularJS 1.0.2 with jQuery 1.8.2 and I'm trying to have AngularJS inject dependencies into objects, like it does for controllers. You can find a basic example on jsFiddle, in there you'll find two controllers (List and NewItem), an object (Item) and a module with a service (named services and communication respectively).

My problem is with Item:

var Item = function (name, price) {
    var self = this;

    self.name = name;
    self.price = price;

    self.pretty = function () {
        return self.name + ": " + self.price;
    };
};

In it I need to use some things outside, let's say I want the pretty method to format the price property to a currency-aware string:

self.pretty = function () {
    return self.name + ": " + $filter("currency")(self.price);
};

But this won't work, as $filter is not defined. (Mind you, the usage of $filter is only an example, it could be anything.)

And modifying var Item = function (name, price) { to var Item = function ($filter, name, price) { won't work too, as it's not AngularJS who's creating the object (as in the case of the controllers), it's me.

So, how can I have AngularJS create the object for me, or have it resolve the dependency I need?

Something like var item = angular.create(Item, $scope.name, $scope.price); or var item = new Item(angular.inject("filter"), $scope.name, $scope.price); I think...

Upvotes: 6

Views: 3909

Answers (1)

pkozlowski.opensource
pkozlowski.opensource

Reputation: 117370

It is possible to ask AngularJS to instantiate your own objects (and inject dependencies into them!) by using the $injector service and its instantiate(Type, locals) method.

For example, given a constructor like this:

var Item = function ($filter, name, price) {
    var self = this;

    self.name = name;
    self.price = price;

    self.pretty = function () {
        return $filter('json')(self);
    };
};

one could create an instance of Item like so:

var item = $injector.instantiate(Item, { name: $scope.name, price: $scope.price });

Please note that the instantiate method accepts 2 arguments:

  • Type: a constructor function.
  • locals: a hash of values that should not be injected but rather taken as-is.

Here is a working jsFiddle (a simplified version of the initial one).

Upvotes: 16

Related Questions