注入的服务在构造函数中未定义

时间:2016-07-06 19:54:17

标签: angularjs angular angular2-injection

对于这张纸条,我对Angular(1或2)不太感兴趣。

我正在尝试编写一个“超级”Http层,以避免在任何地方放置相同的标题。

import {Http, ConnectionBackend, RequestOptions, Response, Headers} from '@angular/http';
import {Observable} from 'rxjs';
import {LoadingService} from "../../services/loading.service";

export class HttpLoading extends Http {
    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions,
        private _ls: LoadingService )
    {
        super(backend, defaultOptions);
    }

    getPostPutHeader() {
        var authHeader = new Headers();
        authHeader.append("Authorization", "Bearer "+ localStorage.getItem('token') );
        authHeader.append('Content-Type', 'application/json');
        return authHeader;
    }

    post(url: string, data:any):Observable<Response> {
        this._ls.isLoading = true; // Exception here: this._ls is undefined
        return super.post(url, data, { headers: this.getPostPutHeader() })
            .map(res => {
                this._ls.isLoading = false;
                return res;
            });
    }
}

用于判断请求何时执行的服务;它是在上面的HttpLoading类中注入的。

import {Injectable} from '@angular/core';

@Injectable()
export class LoadingService {
    isLoading: boolean = false;
}

我的引导程序中有很多东西,包括HttpLoading,LoadingService和ConnectionBackend(对于最后一个,如果它不在这里,我会得到一个例外)。

bootstrap(AppComponent, [
    ConnectionBackend,
    HttpLoading,
    APP_ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    LoadingService,
    disableDeprecatedForms(),
    provideForms()
])

问题是我第一次调用HttpLoading的{​​{1}}方法(在另一项服务中)时,我在post处获得了一个例外,因为this._ls.isLoading是未定义,我无法理解为什么。

如果您需要更多信息,请告诉我。

修改

this._ls已正确注入我的LoadingService(主要组件)。

AppComponent

潜在解决方案

您的公共/私人参数似乎必须首先放在列表中。我会让比我更熟练的人解释原因,但是......

//imports
//@Component
export class AppComponent {
    requesting:boolean = false;

    constructor(public authService: AuthService, private router: Router, private _ls: LoadingService) {
    }

    navigate(route:string) {
        this._ls.isLoading = true;
        this.router.navigate([route])
            .then(() => this._ls.isLoading = false);
    }
}

3 个答案:

答案 0 :(得分:2)

在引导您的应用程序时,我会在提供程序中以这种方式配置您的HttpLoading类:

bootstrap(AppComponent, [
  (...)
  HTTP_PROVIDERS,
  {
    provide:Http,
    useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, loadingService: LoadingService) => {
      return new HttpLoading(backend, defaultOptions, loadingService);
    },
    deps: [XHRBackend, RequestOptions, LoadingService]
  }
]);

原因是您希望将自己的类用于Http提供程序。您需要通过HttpLoading类更改Http提供程序后面的类。请注意在HTTP_PROVIDERS之后定义它。

为了能够向您的班级注入XHRBackend的实例,您需要使用useFactory ...

答案 1 :(得分:0)

好的,我知道这看似微不足道,但尝试创建一个变量并在构造函数中初始化它

答案 2 :(得分:0)

延长@Thierry Templier的答案。我正在使用Angular v4,我的经验是你需要提供你的扩展构造函数所需的所有依赖项,并且按正确的顺序 - 我想这是一种传统的方法,从angular 1.x开始。

我的例子:

//这是我的扩展类(仅限相关部分)

@Injectable()
export class HttpService extends Http {

    constructor(
        backend: ConnectionBackend,
        defaultOptions: RequestOptions,

        private router: Router,
        private loaderService: LoaderService,
        private modalService: ModalService,
        private localStorageService: LocalStorageService
    )
    {
        super(backend, defaultOptions)
    }

//这是在app.module.ts中定义的提供者工厂:

export function httpClientFactory(
        backend: XHRBackend,
        defaultOptions: RequestOptions,
        router: Router,
        loaderService: LoaderService,
        modalService: ModalService,
        localStorageService: LocalStorageService
    ) : Http
{
    return new HttpService(
        backend,
        defaultOptions,
        router,
        loaderService,
        modalService,
        localStorageService
    );
}

这是app.module.ts中的配置(刚离开相关部分):

providers: [
    ModalService
    LocalStorageService,
    LoaderService,
    {
        provide: HttpService,
        useFactory: httpClientFactory,
        deps: [XHRBackend, RequestOptions, Router, LoaderService, ModalService, LocalStorageService]
    }

注意:请注意在配置中声明deps与工厂构造函数相比的顺序..它是相同的