Angular 2 延迟加载和应用程序范围的单例 - 自定义 Http Class 不工作

Angular 2 Lazy Loading and Application-wide singletons - Custom Http Class Not working

我正在尝试使用 Angular 2 路由器延迟加载来减少初始加载时间。

在我的应用程序中,我自定义了 Angular 的原始 Http 服务,以便在启动任何 http 请求时显示一个加载器,我在完成时隐藏它。

目前,我有一个 GlobalService(这是一个应用程序范围的单例),它保存加载栏的当前状态和扩展 Angular 原始 Http class 的 HttpLoading class。

在 AppModule 中,我将两者都添加到提供程序中,以便它们在应用程序范围内可用:

export function httpFactory(backend: XHRBackend, defaultOptions: RequestOptions, globalService: GlobalService) {
        return new HttpLoading(backend, defaultOptions, globalService);
    }

providers: [
            GlobalService,
            {
                provide: Http,
                useFactory: httpFactory,
                deps: [XHRBackend, RequestOptions, GlobalService]
            }
        ],

我有以下 AppModule:

//angular
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Http, XHRBackend, HttpModule, RequestOptions, JsonpModule } from '@angular/http';
import { NgModule } from '@angular/core';

//material
import { MdProgressBarModule } from '@angular2-material/progress-bar';

import { HomeModule } from './home/home.module';

import { AppComponent } from './app.component';

//services
import { GlobalService } from './shared/services/global.service';
import { HttpLoading } from './shared/services/http-loading';

//routing
import { routing } from './app.routing';

export function httpFactory(backend: XHRBackend, defaultOptions: RequestOptions, globalService: GlobalService) {
    return new HttpLoading(backend, defaultOptions, globalService);
}

@NgModule({
    imports: [
        //angular
        BrowserModule,
        FormsModule,
        HttpModule,
        JsonpModule,
        ReactiveFormsModule,
        routing,

        //material
        MdProgressBarModule.forRoot(),
        HomeModule,
    ],
    declarations: [
        AppComponent,
    ],
    providers: [
        GlobalService,
        {
            provide: Http,
            useFactory: httpFactory,
            deps: [XHRBackend, RequestOptions, GlobalService]
        }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

下面是我的 HttpLoading Class:

import { Http, ConnectionBackend, RequestOptions, RequestOptionsArgs, Response, Headers } from '@angular/http';
import { Injectable } from '@angular/core';
import { GlobalService } from './global.service';

import { Observable } from 'rxjs/Observable';
import "rxjs/add/operator/catch";

export class HttpLoading extends Http {

constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _gs: GlobalService) {
        super(backend, defaultOptions);
    }

get(url: string, options?: RequestOptionsArgs): Observable<any> {
        this._gs.isLoading = true;

        return super.get(url, options)
            .map(res => {
                this._gs.isLoading = false;
                return res.json();
            });
    }

}

下面是我的 GlobalService

从'@angular/core'导入{可注入,注入};

@Injectable() 导出 class 全球服务 { public isLoading: boolean = false; }

我尝试在下面创建 SharedModule,我认为我会在 AppModule 中注入它,它会解决问题:

import { NgModule, ModuleWithProviders } from "@angular/core";
import { Http, XHRBackend, HttpModule, RequestOptions, JsonpModule } from '@angular/http';
import { GlobalService } from './shared/services/global.service';
import { HttpLoading } from './shared/services/http-loading';

export function httpFactory(backend: XHRBackend, defaultOptions: RequestOptions, globalService: GlobalService) {
    return new HttpLoading(backend, defaultOptions, globalService);
}

@NgModule({
    imports: [
        //angular
        HttpModule,
        JsonpModule
    ]
})
export class SharedModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [GlobalService,
                {
                    provide: Http,
                    useFactory: httpFactory,
                    deps: [XHRBackend, RequestOptions, GlobalService]
                }]
        };
    }
}

并将我的 AppModule 更新为以下内容:

//angular
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Http, XHRBackend, HttpModule, RequestOptions, JsonpModule } from '@angular/http';
import { NgModule } from '@angular/core';

//material
import { MdProgressBarModule } from '@angular2-material/progress-bar';

import { HomeModule } from './home/home.module';
import { SharedModule } from './../shared.module';

import { AppComponent } from './app.component';


//routing
import { routing } from './app.routing';


@NgModule({
    imports: [
        //angular
        BrowserModule,
        FormsModule,
        HttpModule,
        JsonpModule,
        ReactiveFormsModule,
        routing,

        //material
        MdProgressBarModule.forRoot(),
        HomeModule,
        SharedModule
    ],
    declarations: [
        AppComponent,
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

但是没有用。每当我访问任何具有 http 调用的路由时,它都会在控制台上抛出错误。

例如,在 ngOnInit 的 HomeCompnent 中,我进行了一个 http 调用来获取一些数据。但是当我移动到这个组件时,我在控制台中显示以下错误。

EXCEPTION: _super.prototype.get.call(...).map is not a function


core.umd.js:3468 TypeError: _super.prototype.get.call(...).map is not a function
    at HttpLoading.get (http-loading.js:50)
    at HomeComponent.ngOnInit

任何人都可以指导我做错了什么吗?

方法一:

在 HttpLoading class 文件中,添加

import 'rxjs/add/operator/map';

方法二(针对systemjs):

如果您这样做,则不需要方法 1。

在main.ts

import 'rxjs';

在systemjs.config.js;

map: {
  'rxjs': 'node_modules/rxjs',
},
packages: {
  'rxjs': { main: 'bundles/Rx.min.js', defaultExtension: 'js' },