How do I inject a dependency in a class definition of a component?

馋奶兔 提交于 2020-05-27 04:36:05

问题


I have this class-defined component (transpiled later by webpack and babel back into ES5). I need to use the $http service in one of its methods. How do I do that? Where do I inject $http as a dependency? If I do it in the constructor arguments, I get an error as if I hadn't injected it at all. Maybe classes is not the way to go here?

angular.module('myApp').component('home', {
    template: require('./home.component.html'),
    controller: class HomeCtrl {
        constructor() {
        }
        doMe() {
            $http.get('http://www.yahoo.com/');
        }
    }
});

回答1:


ES2015 classes (or transpiled classes) are just syntactic sugar over prototypal inheritance. What this means is that the methods you define are put on the prototype of the "class". In order to be able to access the dependencies injected in the constructor, you need to somehow store them for later reference by the prototype method.

This is usually done by putting them on the instance:

function HomeController($http) {
  this.$http = $http;
}
HomeController.prototype.doMe = function() {
  this.$http.get('http://www.yahoo.com/');
};

In class-based syntax this translates to:

class HomeController {
  constructor($http) {
    this.$http = $http;
  }

  doMe() {
    this.$http.get('http://www.yahoo.com/');
  }
}

EDIT:
If you are using TypeScript, you can save some boilerplate by using access modifiers on the constructor arguments. E.g.:

class HomeController {
  constructor(private $http) {}
}

...which is shorthand for:

class HomeController {
  private $http;

  contructor($http) {
    this.$http = $http;
  }
}

EDIT 2:
If you want to make your controller minification-friendly, you can use one of the options described here (possibly along with a tool like ngAnnotate). For example, this is how you could use the "$inject Property Annotation" method:

ES5

HomeController.$inject = ['$http'];
function HomeController($http) {...}
HomeController.prototype.doMe = function() {...}

ES2015

class HomeController {
  constructor($http) {...}

  doMe() {...}
}
HomeController.$inject = ['$http'];

// OR

class HomeController {
  static get $inject() { return ['$http']; }
  constructor($http) {...}

  doMe() {...}
}

TypeScript

class HomeController {
  static $inject = ['$http'];
  constructor(private $http) {}

  doMe() {...}
}



回答2:


The class should have explicit $inject annotation in order to be properly minified:

class HomeCtrl {
    static get $inject() {
        return ['$http'];
    }
    // or unstandardized shortcut:
    // static $inject = ['$http'];

    constructor($http) {
        this.$http = $http;
    }

    doMe() {
         this.$http...
    }
}



回答3:


In the end, I did:

controller: class {
    constructor($http, Restangular, $state) {
        Object.assign(this, {$http, Restangular, $state});
    }
    doMe() {
       // use this.$http, this.Restangular & this.$state freely here
    }
}


来源:https://stackoverflow.com/questions/41178643/how-do-i-inject-a-dependency-in-a-class-definition-of-a-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!