Angular2子类的Http抛出错误

时间:2016-04-12 14:14:26

标签: angular angular2-http

我正在处理身份验证标头,一个解决方案是创建一个子类,从'angular2 / http'扩展Http并添加默认的auth标头。我使用github中的相同代码,但它会抛出 EXCEPTION: TypeError: backend.createConnection is not a function in [null] code here。但是当我将它改回angular2 / http时,一切正常。我找不到有关此异常消息的任何信息。谢谢你的帮助!

更新 我使用的方法与样本相同。 这是我的服务:

import {Injectable} from 'angular2/core';
// import {Http} from 'angular2/http';
import {Headers, Response} from 'angular2/http';
import {Http} from '../common/http';
import {Category} from '../model/category';
import 'rxjs/add/operator/map';

@Injectable()
export class CategoryService {
  constructor(private http:Http) {}
  getCategories() {
      return this.http.get('http://www.google.com')
      .map(res => res.json());
  }

  getCategory(id: string) {
      return this.http.get('http://localhost:8080/api/category/'+id)
      .map(res => res.json());
  }
}

这是我的/ commom / http

import {Observable} from "rxjs/Observable";
import {Injectable} from "angular2/core";
import {Http as NgHttp,  RequestOptionsArgs, RequestOptions,  Headers, Response, ConnectionBackend} from "angular2/http";

const mergeAuthToken = (options:RequestOptionsArgs) => {
  let newOptions = new RequestOptions({}).merge(options);
  let newHeaders = new Headers(newOptions.headers);
  let access_token = localStorage.getItem('access_token');
  newHeaders.set('Authorization', 'bearer '+ access_token);
  newHeaders.set('Accept', 'application/json');
  newHeaders.set('Content-Type', 'application/json');
  newOptions.headers = newHeaders;
  return newOptions;
};

@Injectable()
export class Http extends NgHttp {
    constructor(_backend: ConnectionBackend, _defaultOptions: RequestOptions) {
        super(_backend, _defaultOptions);
    }
  get(url:string, options?:RequestOptionsArgs):Observable<Response> {
      return super.get(url, mergeAuthToken(options));
  }

  post(url:string, body:string, options?:RequestOptionsArgs):Observable<Response> {
    return super.post(url, body, mergeAuthToken(options));
  }...
}

这是我的app.component的一部分:

import { Http } from '../common/http';
import { SecurityRouterOutlet } from '../router/securityRouter';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import {HTTP_PROVIDERS, ConnectionBackend } from 'angular2/http';

@Component({
    selector: 'my-app',
    templateUrl: 'app/view/app.component.html',
    styleUrls: ['app/view/app.component.css'],
    directives: [SecurityRouterOutlet, ROUTER_DIRECTIVES],
    providers: [
        ROUTER_PROVIDERS,
        HTTP_PROVIDERS,
        CategoryService,
        LoginService,
        ConnectionBackend,
        Http
    ]
})

如果需要更多代码详细信息,请告知我们。谢谢!

Update2 正如@Thierry Templier建议的那样,我将Http更改为我的common / http文件中的AuthHttp,以及类别服务和app.component.ts,但这没有用。

完整的异常堆栈:

TypeError: backend.createConnection is not a function  angular2.dev.js:23877 
    at httpRequest (http.dev.js:941)
    at AuthHttp.Http.get (http.dev.js:980)
    at AuthHttp.get (http.ts:24)
    at CategoryService.getCategories (category.service.ts:16)
    at DashboardComponent.ngOnInit (dashboard.component.ts:15)
    at AbstractChangeDetector.ChangeDetector_HostDashboardComponent_0.detectChangesInRecordsInternal (viewFactory_HostDashboardComponent:21)
    at AbstractChangeDetector.detectChangesInRecords (angular2.dev.js:9609)
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9592)
    at AbstractChangeDetector._detectChangesContentChildren (angular2.dev.js:9665)
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9593)

dashboard.component:

import { Component, OnInit } from 'angular2/core';
import { Router } from 'angular2/router';
import { Category } from '../model/category';
import { CategoryService } from '../service/category.service';

@Component({
    selector: 'my-dashboard',
    templateUrl: 'app/view/dashboard.component.html',
    styleUrls: ['app/view/dashboard.component.css']
})
export class DashboardComponent implements OnInit {
    categories: Category[] = [];
    constructor(private _router: Router, private _categoryService: CategoryService) { }
    ngOnInit() {
     this._categoryService.getCategories().subscribe(
          data => { this.categories = data },
          err => console.error(err)
      );
    }
    gotoDetail(category: Category){
        let link = ['CategoryDetail', { id: category.id }];
        this._router.navigate(link);
    }
}

我使用的是最新版本:

{
    "name": "angular2quickstart",
    "version": "1.0.0",
    "scripts": {
    "postinstall": "npm run typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" ",
    "typings" : "typings"
},
  "license": "ISC",
"dependencies": {
    "angular2": "2.0.0-beta.13",
    "systemjs": "0.19.25",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.3",
    "rxjs": "5.0.0-beta.4",
    "zone.js": "0.6.9"
},
"devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.0.1",
    "typescript": "^1.7.5",
    "typings": "^0.7.12"
    }
}

1 个答案:

答案 0 :(得分:0)

您在定义关联的提供商时无法使用useClass,但useFactory以这种方式:

bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  provide(Http, {
    useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
    deps: [XHRBackend, RequestOptions]
  })
]);

这样你就可以提供后端注入。

修改

我发现您定义班级的方式存在问题。你应该尝试这样的事情:

export class CustomHttp extends Http {
  (...)
}

并使用provide函数注册它,如上所述。