服务中的角度访问组件方法,没有提供程序错误

时间:2018-03-06 15:40:57

标签: angular

我收到了这个错误,所以我显然在这里遗漏了一些东西

ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[ApiHandlerService -> ApiHandlerModalComponent]: 
  StaticInjectorError(Platform: core)[ApiHandlerService -> ApiHandlerModalComponent]: 
    NullInjectorError: No provider for ApiHandlerModalComponent!

我有一个服务,在每个API调用上调用,以确定服务器是否返回异常而不是预期的有效负载。然后,我有一个模态组件,如果该情况为真,则需要显示。所以我的服务是这样的,我导入模态组件以调用showModal()方法并将有效负载传递给它:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ApiHandlerModalComponent } from 'app/modules/ui/components/api-handler-modal/api-handler-modal.component';


@Injectable()
export class ApiHandlerService {

    exception: any = [];

    constructor(
        private router: Router,
        private http: HttpClient,
        private apiHandler: ApiHandlerModalComponent
    ) {
    }

    responseHandler(response) {
        if (response.success) {
            const obj = {
                exception: false,
                payload: response.payload
            };
            return obj;
        } else {
            const obj = {
                exception: true,
                message: response.exception.message,
                segNum: response.exception.seqNum
            };
            this.apiHandler.showModal(obj);
            return obj;
        }
    }

    errorHandler(err) {
        if (err instanceof HttpErrorResponse) {
            if (err.status === 401) {
                this.router.navigate(['/app-login']);
            }
        }
    }

}

然后在共享模块中我有模态组件:

import { Component, ViewChild  } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap/modal';

@Component({
  selector: 'app-api-handler-modal',
  templateUrl: './api-handler-modal.component.html'
})
export class ApiHandlerModalComponent {

    @ViewChild('autoShownModal') autoShownModal: ModalDirective;

    isModalShown = false;

    constructor() { }

    showModal(obj?): void {
        this.isModalShown = true;
        console.log(obj);
    }

    hideModal(): void {
        this.autoShownModal.hide();
    }

    onHidden(): void {
        this.isModalShown = false;
    }

}

所以根据错误我没有设置提供者。我想我只是有点迷失在哪里以及如何解决这个问题?

app.module.ts:

/* import angular modules */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { BreadcrumbsModule } from 'ng2-breadcrumbs';
import { UiModule } from 'app/modules/ui/ui.module';

/* import routers */
import { Routing } from './app.routing';

/* import authentication */
import { LoginService } from './modules/login/services/login.service';
import { AuthService } from './auth/auth.service';
import { AuthGuard } from './auth/gaurds/auth.guard';
import { AdminGuard } from './auth/gaurds/admin.gaurd';

/* import components */
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { SidebarComponent } from './components/sidebar/sidebar.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';

export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    SidebarComponent,
    PageNotFoundComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BsDropdownModule.forRoot(),
    NgbModule.forRoot(),
    TranslateModule.forRoot({
        loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
        }
    }),
    BreadcrumbsModule,
    UiModule,
    Routing,
  ],
  providers: [
    LoginService,
    AuthService,
    AuthGuard,
    AdminGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

2 个答案:

答案 0 :(得分:0)

您需要将 ApiHandlerModalComponent 添加到providers数组中,因此您的app.module.ts应为:

/* import angular modules */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { BreadcrumbsModule } from 'ng2-breadcrumbs';
import { UiModule } from 'app/modules/ui/ui.module';

/* import routers */
import { Routing } from './app.routing';

/* import authentication */
import { LoginService } from './modules/login/services/login.service';
import { AuthService } from './auth/auth.service';
import { AuthGuard } from './auth/gaurds/auth.guard';
import { AdminGuard } from './auth/gaurds/admin.gaurd';

/* import components */
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { SidebarComponent } from './components/sidebar/sidebar.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';

export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    SidebarComponent,
    PageNotFoundComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BsDropdownModule.forRoot(),
    NgbModule.forRoot(),
    TranslateModule.forRoot({
        loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
        }
    }),
    BreadcrumbsModule,
    UiModule,
    Routing,
  ],
  providers: [
    LoginService,
    AuthService,
    AuthGuard,
    AdminGuard,
    ApiHandlerModalComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

答案 1 :(得分:0)

您的应用程序更好的解决方案是使用主题(行为或重播):

要做你想做的事,你必须执行以下步骤:

@Injectable()
export class ApiHandlerService {

    exception: any = [];
    heyShowModal = new ReplaySubject<any>(1);  <---add Subject

    constructor(
        private router: Router,
        private http: HttpClient,
        //private apiHandler: ApiHandlerModalComponent <---remove it
    ) {
    }

    responseHandler(response) {
        if (response.success) {
            const obj = {
                exception: false,
                payload: response.payload
            };
            return obj;
        } else {
            const obj = {
                exception: true,
                message: response.exception.message,
                segNum: response.exception.seqNum
            };
            this.heyShowModal.next(obj);  <-- next method to call modal in component
            return obj;
        }
    }

    errorHandler(err) {
        if (err instanceof HttpErrorResponse) {
            if (err.status === 401) {
                this.router.navigate(['/app-login']);
            }
        }
    }

}

然后在组件中

@Component({
  selector: 'app-api-handler-modal',
  templateUrl: './api-handler-modal.component.html'
})
export class ApiHandlerModalComponent, OnInit, OnDestroy {

@ViewChild('autoShownModal') autoShownModal: ModalDirective;

  isModalShown = false;
  subscription: Subscription;

  constructor(private apiHandlerService :ApiHandlerService) { } // <-- here you have to inject service

  ngOnInit() {  // <--here was my mistake
      this.subscription = this.apiHandlerService.heyShowModal.subscribe(
          obj => this.showModal(obj);
      )
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
}

  showModal(obj?): void {
    this.isModalShown = true;
    console.log(obj);
}

...

}

将ApiHandlerService放入要使用它的提供程序中。