角度7:未定义注入的服务

Rid*_*ANI 9 dependency-injection typescript ecmascript-6 jhipster angular

我试图在LoginService中注入AccountService,但不会这样做,accountService未定义,但另一方面authServiceProvider已定义。

相反,它完美地注入了footerComponent中。

那么,为什么将AccountService完美地注入FooterComponent并导致LoginService出错。

我不知道问题出在哪里。

import { Injectable } from '@angular/core';
import { AccountService } from 'app/core/auth/account.service';
import { AuthServerProvider } from 'app/core/auth/auth-jwt.service';
@Injectable({ providedIn: 'root' })
export class LoginService {
    constructor(public accountService: AccountService, private authServerProvider: AuthServerProvider) {
        console.log(this.accountService); //  is undefined 
        console.log(this.authServerProvider); // is defined
}
Run Code Online (Sandbox Code Playgroud)

这是AuthentificationService

@Injectable({ providedIn: 'root' })
export class AuthServerProvider {
    constructor(private http: HttpClient, private $localStorage: LocalStorageService, private $sessionStorage: SessionStorageService) {}
Run Code Online (Sandbox Code Playgroud)

这是AccountService

@Injectable({ providedIn: 'root' })
export class AccountService {
    private userIdentity: any;
    private authenticated = false;
    private authenticationState = new Subject<any>();
    constructor(private languageService: JhiLanguageService, private sessionStorage: SessionStorageService, private http: HttpClient) {}
Run Code Online (Sandbox Code Playgroud)

我试图在其他组件中使用AccountService,并且注入完美

import { Component } from '@angular/core';
import { AccountService } from 'app/core';
@Component({
    selector: 'jhi-footer',
    templateUrl: './footer.component.html',
    styleUrls: ['./footer.component.scss']
})
export class FooterComponent {

    constructor( private accountService: AccountService) {
        console.log(this.accountService); // It is defined

    }
}
Run Code Online (Sandbox Code Playgroud)

这是app.module.ts

import './vendor.ts';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgbDatepickerConfig } from '@ng-bootstrap/ng-bootstrap';
import { Ng2Webstorage } from 'ngx-webstorage';
import { NgJhipsterModule } from 'ng-jhipster';
import { AuthInterceptor } from './blocks/interceptor/auth.interceptor';
import { AuthExpiredInterceptor } from './blocks/interceptor/auth-expired.interceptor';
import { ErrorHandlerInterceptor } from './blocks/interceptor/errorhandler.interceptor';
import { NotificationInterceptor } from './blocks/interceptor/notification.interceptor';
import { SharedModule } from 'app/shared';
import { CoreModule } from 'app/core';
import { AppRoutingModule } from './app-routing.module';
import { HomeModule } from './home/home.module';
import { AccountModule } from './account/account.module';
import { EntityModule } from './entities/entity.module';
import * as moment from 'moment';
// jhipster-needle-angular-add-module-import JHipster will add new module here
import { JhiMainComponent, NavbarComponent, FooterComponent, PageRibbonComponent, ActiveMenuDirective, ErrorComponent } from './layouts';
@NgModule({
    imports: [
        BrowserModule,
        Ng2Webstorage.forRoot({ prefix: 'jhi', separator: '-' }),
        NgJhipsterModule.forRoot({
            // set below to true to make alerts look like toast
            alertAsToast: false,
            alertTimeout: 5000,
            i18nEnabled: true,
            defaultI18nLang: 'en'
        }),
        SharedModule.forRoot(),
        CoreModule,
        HomeModule,
        AccountModule,
        // jhipster-needle-angular-add-module JHipster will add new module here
        EntityModule,
        AppRoutingModule
    ],
    declarations: [JhiMainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AuthInterceptor,
            multi: true
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AuthExpiredInterceptor,
            multi: true
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: ErrorHandlerInterceptor,
            multi: true
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: NotificationInterceptor,
            multi: true
        }
    ],
    bootstrap: [JhiMainComponent]
})
export class AppModule {
    constructor(private dpConfig: NgbDatepickerConfig) {
        this.dpConfig.minDate = { year: moment().year() - 100, month: 1, day: 1 };
    }
}
Run Code Online (Sandbox Code Playgroud)

这是core.module。

import { NgModule, LOCALE_ID } from '@angular/core';
import { DatePipe, registerLocaleData } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { Title } from '@angular/platform-browser';
import locale from '@angular/common/locales/en';
@NgModule({
    imports: [HttpClientModule],
    exports: [],
    declarations: [],
    providers: [
        Title,
        {
            provide: LOCALE_ID,
            useValue: 'en'
        },
        DatePipe
    ]
})
export class CoreModule {
    constructor() {
        registerLocaleData(locale);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助。

ZIN*_*oud 6

除非在某些情况下您希望仅当使用者导入特定的@NgModule时才希望该服务可用,否则您应该始终在根注入器中提供服务。

尝试添加您想注入到您的服务providers : [ ]core.module

import { NgModule, LOCALE_ID } from '@angular/core';
import { DatePipe, registerLocaleData } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { Title } from '@angular/platform-browser';
import locale from '@angular/common/locales/en';
@NgModule({
    imports: [HttpClientModule],
    exports: [],
    declarations: [],
    providers: [
        AccountService,
        Title,
        {
            provide: LOCALE_ID,
            useValue: 'en'
        },
        DatePipe
    ]
})
export class CoreModule {
    constructor() {
        registerLocaleData(locale);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的AccountService中替换 @Injectable({ providedIn: 'root' })@Injectable()

@Injectable()
export class AccountService {
    private userIdentity: any;
    private authenticated = false;
    private authenticationState = new Subject<any>();
    constructor(private languageService: JhiLanguageService, private sessionStorage: SessionStorageService, private http: HttpClient) {}
Run Code Online (Sandbox Code Playgroud)

  • 我认为问题的重点是为什么它不能与`@Injectable({providedIn:'root'})`一起使用。这个答案缓解了这个问题背后的问题,但基本上违背了 Angular 文档,即“从 Angular 6.0 开始,创建单例服务的首选方法是将providIn 设置为服务的 @Injectable() 装饰器上的根”。 (9认同)
  • 谢谢,兄弟它可以工作,但我不知道为什么在这种情况下它可以工作,我认为在角度7中,如果我们使用了ProvideIn属性,则无需将服务添加到提供程序中。 (4认同)
  • 感谢您的链接。我到处都没有解决我的问题。直到我想起使用var this = that等的旧时代...我才变得未定义,因为我将普通函数作为回调而不是箭头函数进行了传递。他们有不同的范围。希望有人偶然发现:) (2认同)

小智 5

我也发生了同样的事情,解决方案是用户跨度提到的解决方案

->在回调中传递箭头函数而不是常规函数。箭头函数没有它自己的这个

常规功能和箭头功能之间的差异在这里

  • 我看不到问题中的代码与箭头函数之间的关系。OP只谈论“构造函数”,他从不调用“new LoginService(...)”,那么为什么会出现上下文问题呢? (3认同)