代码之家  ›  专栏  ›  技术社区  ›  naspinski

angular2服务基类继承-为什么“this”为空?

  •  3
  • naspinski  · 技术社区  · 9 年前

    我试图使用继承为我的服务创建一个通用的错误处理程序,但由于某种原因,当它到达错误处理程序本身时,“this”看起来总是空的,我不知道为什么。我可以很好地进入错误处理程序,但我总是得到:

    异常:未捕获(承诺中):类型错误:无法读取属性 空的“http”

    你知道我错过了什么/做错了什么吗?不确定“this”怎么可能为空?

    这是我的整个服务基类:

    import { Injectable } from '@angular/core';
    import { Http } from '@angular/http';
    
    @Injectable()
    export class HttpServiceBase {
    
        constructor(public http: Http) {
            console.log('http', this.http); //just do this to prove that it is there - it is!
        }
    
        handleError(error: any): Promise<any> {
            console.error('Application Error', error); //this logs fine
    
            // TypeError: Cannot read property 'http' of null
            this.http.get('/Account/IsLoggedIn')
                .map(response => console.log('RESPONSE: ', response));
    
            return Promise.reject(error.message || error);
        }
    }
    

    这是我的继承类:

    import 'rxjs/add/operator/toPromise';
    import { Injectable } from '@angular/core';
    import { Headers, Http } from '@angular/http';
    import { HttpServiceBase } from './http-service.base';
    import { Hero } from './hero';
    
    @Injectable()
    export class HeroService extends HttpServiceBase {
    
        private headers = new Headers({ 'Content-Type': 'application/json' });
        private heroesUrl = 'http://localhost:57569/Home/Heroes';
    
        constructor(http: Http) { super(http); }
    
        getHeroes(): Promise<Hero[]> {
            console.log('getting heroes');
    
            return this.http.get(this.heroesUrl + '-force-error') //so it will error out
                .toPromise()
                .then(response => response.json() as Hero[] )
                .catch(this.handleError);
        }
    }
    
    3 回复  |  直到 9 年前
        1
  •  4
  •   Estus Flask    9 年前

    对于应该用作回调的方法,建议在构造时将它们绑定到上下文。在TypeScript中,这可以通过类字段和箭头方法实现:

    constructor(public http: Http) {}
    
    handleError = (error: any): Promise<any> { ... }
    

    与绑定方法调用相反,这消除了不正确上下文的可能性。

    更优选的方式可以是:

    constructor(public http: Http) {
      this.handleError = this.handleError.bind(this);
    }
    
    handleError(error: any): Promise<any> { ... }
    

    它做同样的事情,但具有更好的可测试性,因为它允许监视/模拟 HttpServiceBase.prototype.handleError 在类实例化之前。

        2
  •  4
  •   toskv    9 年前

    这是因为你路过 手误 作为捕捉函数的函数。当它被调用时,它将有一个不同的 对象

    您可以将箭头函数传递给 接住 保持相同的上下文。

    .catch(error => this.handleError(error));
    

    你必须记住,即使 手误 定义为类上的一个方法,它的行为仍与任何其他函数一样。

        3
  •  2
  •   Paarth    9 年前

    这有可能修复它吗?

    .catch(this.handleError.bind(this));