How to Inject Angular2 Http service into es6/7 Class?

前端 未结 4 492
生来不讨喜
生来不讨喜 2020-12-03 21:52

If I use es6/7 (babel - stage 1) instead of TypeScript, how are services, and specifically Http, injected?

Here\'s my component JS:

import {Compone         


        
相关标签:
4条回答
  • 2020-12-03 22:13

    Since you have @Decorators enabled in Babel

    ...I'll fine-tune this answer to work with your specific setup.

    1. You're missing HTTP_PROVIDERS

    The HTTP_PROVIDERS constant includes a number of functions required to handle HTTP requests/responses.

    import {Http, HTTP_PROVIDERS} from 'angular2/http';    
    
    @Component({
      selector: 'login',
      providers: [ HTTP_PROVIDERS ]
    })
    

    2. You need to desugar the DI (Dependency Injection) syntax

    As mentioned in @alexpods' answer.

    Remove the static typing

    constructor(http) {
    

    @Inject handles DI implicitly but is only supported in Angular2+Typescript. Since you're using Angular2+ES6 you need to attach a static getter parameter to your class to provide the ES6-specific equivalent.

    static get parameters() {
        return [[Http]];
    }
    

    3. You need to bind the Http instance to your class in the constructor

    By doing this, it will become accessible in your authenticate() method.

    constructor(http) {
        this.http = http;
        console.log('http', this.http);
    }
    

    ...and the full implementation:

    import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
    import {Http, HTTP_PROVIDERS} from 'angular2/http';
    
    @Component({
      selector: 'login',
      // required for Http
      providers: [ HTTP_PROVIDERS ]
    })
    @View({
      templateUrl: './components/login/login.html',
      styleUrls: ['components/login/login.css'],
      directives: [CORE_DIRECTIVES],
      encapsulation: ViewEncapsulation.Emulated
    })
    export class Login {
      constructor(http) {
        // bind http to your class during construction
        //   so it's available to authenticate()
        this.http = http;
      }
    
      // Angular2 DI desugar'd
      static get parameters() {
        return [[Http]];
      }
    
      authenticate(username, password) {
        this.http.get('/login');
      }
    }
    

    Aside: I know for a fact this works because I'm using it for the <ng2-markdown> component on EvanPlaice.com.

    0 讨论(0)
  • 2020-12-03 22:14

    With babel-plugin-angular2-annotations, you can inject services with constructor parameter type annotations just like TypeScript.

    Install babel plugins:

    npm install -D babel-plugin-angular2-annotations babel-plugin-transform-decorators-legacy babel-plugin-transform-class-properties babel-plugin-transform-flow-strip-types babel-preset-es2015
    

    .babelrc:

    {
      "plugins": [
        "angular2-annotations",
        "transform-decorators-legacy",
        "transform-class-properties",
        "transform-flow-strip-types"
      ],
      "presets": [
        "es2015"
      ]
    }
    

    and voila!

    import {Component, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
    import {Http} from 'angular2/http';
    
    @Component({
      selector: 'login'
    })
    @View({
      templateUrl: './components/login/login.html',
      styleUrls: ['components/login/login.css'],
      directives: [CORE_DIRECTIVES],
      encapsulation: ViewEncapsulation.Emulated
    })
    export class Login {
      constructor(http: Http) {
        console.log('http', http);
        this.http = http;
      }
    
      authenticate(username, password) {
        this.http.get('/login');
      }
    }
    

    Note that the type signature is used only for a hint for dependency injection and not used for type-checking.

    0 讨论(0)
  • 2020-12-03 22:19

    How I've already answered it here, If you write code in ES7, use static getter for parameters property to specify injections into constructor of your component. For example:

    import { Http } from 'angular2/http';
    // other imports ...
    
    // component decorators ...
    export class Login {
    
      static get parameters() {
        return [[Http]];
      }
    
      constructor(http) {
        this.http = http;
        console.log('http', http);
      }
    
      // other methods
    }
    

    I think it most concise method at this moment.

    Remember there is no proposal to support parameter decorators in ES7 at this moment (for example see this issue for Babel).

    0 讨论(0)
  • 2020-12-03 22:24

    Method from the official API Review works for me:

    import {Http, HTTP_PROVIDERS} from 'angular2/http';
    @Component({
      selector: 'http-app',
      viewProviders: [HTTP_PROVIDERS],
      templateUrl: 'people.html'
    })
    class PeopleComponent {
      constructor(http: Http) {
        http.get('people.json')
          .map(res => res.json())
          .subscribe(people => this.people = people);
      }
    }
    
    0 讨论(0)
提交回复
热议问题