简体   繁体   中英

Angular2 Beta dependency injection

I have a NavBar Component which loads the QApi Service, the QApi Service loads the UserService, but I get the following error:

EXCEPTION: No provider for UserService! (NavBarComponent -> QApi -> UserService)

Either I simply don't get the concept of dependency injection, I made a stupid error, or this is just way to complicated compared to native development... Thanks for your help.

Here my code:

UserService:

import {Injectable} from 'angular2/core';
//import {User} from '../data-source-mocks/users';

@Injectable() 
export class UserService {
 public isAuthenticated = true;
}

QApi Service:

import {Injectable} from 'angular2/core';
import {UserService} from '../user/user.service';

@Injectable() 
export class QApi {

constructor(private _userService: UserService) {}

}

NavBar Component:

import {Component} from 'angular2/core';
import {QApi} from '../../services/q-api/q-api';

@Component({
 selector: 'nav-bar',
 template: `Test NavBar`,
 providers: [QApi]
})

export class NavBarComponent {
private _isAuthenticated = false;

constructor(private _QApi: QApi) {}
}

EDIT:

First of all: Thanks for alle the great answers each and every single one helped me to understand dependency injection better, especially this article: https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

I changed my QApi class to this:

import {Injectable, Inject, Injector} from 'angular2/core';
import {UserService} from '../user/user.service';
import {CardService} from '../card/card.service';

@Injectable()
export class QApi {

constructor() {
    var _injector = Injector.resolveAndCreate([UserService, 
                                               CardService]);

    this.userService = _injector.get(UserService);
    this.cardService = _injector.get(CardService);
}

}

Now it works like I hoped it would. Cant thank you guys enough!!

Add UserService to the component providers :

@Component({
    selector: 'nav-bar',
    template: `Test NavBar`,
    providers: [QApi, UserService] // <- add UserService here
})
export class NavBarComponent { /* ... */ }

Here are two good articles to better understand Angular2 Dependency Injection:

In fact both previous responses are true! ;-)

You need to define the services:

  • Application level . Within the second parameter of the bootstrap function. It contains the list of the providers that are available for the whole application.

     bootstrap(App, [UserService, QApi, ...]); 
  • Component level . Within the providers attribute of the Component annotation. In this case, this is only configured for this component and you need to define this for each component where the QApi service.

     @Component({ selector: 'nav-bar', template: `Test NavBar`, providers: [QApi, UserService] }) 

You also mix things. I mean you can put the UserService provider at the application level and QApi at the component level. In fact what is important is that Angular can find providers for all the involved elements in the processing chaining (with dependency injection). They can come from either component level (1st) or application level (2nd).

Hope that it gives you some additional hints following alexpods and MichaelOryl great answers ;-)

Thierry

List the services in your bootstrap call (wherever you are handling that). Something like the following should work:

bootstrap(App, [UserService, QApi, COMMON_DIRECTIVES, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, HTTP_PROVIDERS]); 
providers// directives added here are available to all children

Then you will have a single instance of each of those services available to the rest of your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM