2017-07-18 11 views
-1

私はTypescriptの抽象クラスについて学んでいます。 thisキーワードは、handleRetryを除き、このクラスのすべてのメソッドで完全に機能します。その方法の最上部にあるconsole.log(this.amiUrl)にしようとしても、それは爆破して見つけられないと私に伝えます。rxjs .let()操作で "this"キーワードを使用できないのはなぜですか?

保護されたキーワードを削除しようとしましたが、誤解していたと思います。変化なし。あなたがコールバックとしてthis.handleRetryを渡しているためです

角4.3

活字体2.4.1

import { HttpHeaders, HttpClient, HttpErrorResponse } from '@angular/common/http'; 
import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 

import { ToastsManager } from 'ng2-toastr/ng2-toastr'; 

import { Store } from '@ngrx/store'; 
import * as uiActions from '../../core/store/actions/ui.actions'; 
import * as fromRoot from '../../core/store/reducers'; 

import { environment } from '../../../environments/environment'; 

@Injectable() 
export abstract class RestService { 
    protected amiUrl = environment.api; 
    protected maxRetryAttempts = 3; 

    constructor (
    private http: HttpClient, 
    private store: Store<fromRoot.State>, 
    private toastr: ToastsManager) { } 

    private get headers(): HttpHeaders { 
    const headers: HttpHeaders = new HttpHeaders(); 
    headers.set('Authorization', 'Bearer ' + environment.accessToken); 
    return headers; 
    } 

    protected get(url: string) { 
    return this.http.get(this.amiUrl + url, { headers: this.headers }) 
     .let(this.handleRetry); 
    } 

    protected post(url: string, payload: any) { 
    return this.http.post(this.amiUrl + url, payload, { headers: this.headers }) 
     .let(this.handleRetry); 
    } 

    protected delete(url: string) { 
    return this.http.delete(this.amiUrl + url, { headers: this.headers }) 
     .let(this.handleRetry); 
    } 

    protected handleRetry<T>(source: Observable<T>): Observable<T> { 
    return source.retryWhen(e => 
     e.scan((errorCount, error) => { 
     if (errorCount >= this.maxRetryAttempts) { 
      this.store.dispatch(new uiActions.ClearRetryNotificationAction); 
      throw error; 
     } else { 
      this.store.dispatch(new uiActions.CreateRetryNotificationAction({ attempt: errorCount + 1, maxAttempts: this.maxRetryAttempts })) 
      return errorCount + 1; 
     } 
     }, 0) 
     .delay(2000)) 
    } 

    protected handleError(err: HttpErrorResponse, customMessage?: string) { 
    this.store.dispatch(new uiActions.CreateErrorNotificationAction(customMessage)); 

    console.log(err.error); 
    console.log(err.status); 
    console.log(err.name); 
    console.log(err.message); 

    if (!environment.production) { 
     this.toastr.error(customMessage); 
    } 

    return Observable.throw(err.message); 
    } 
} 

答えて

0


コールバックが呼び出されるとスコープが変更され、thisRestServiceのインスタンスを参照しなくなります。 (3)メソッドをバインド

... 
.let(source => this.handleRetry(source)) 

(1)bind methodを使用します:

... 
.let(this.handleRetry.bind(this)) 

(2)arrow functionを使用して、あなたが4つのオプションがあり、この問題を解決するには

ctor内:

constructor (
    private http: HttpClient, 
    private store: Store<fromRoot.State>, 
    private toastr: ToastsManager) { 

    this.handleRetry = this.handleRetry.bind(this); 
} 

this.handleRetryを渡すと、既にインスタンスにバインドされており、呼び出されてもそのように保持されます。

インスタンスタイプの機能のプロパティを作成します
handleRetry = <T>(source: Observable<T>): Observable<T> => { 
    ... 
} 

、それはそれはそれにバインドされている矢印の機能だから:

(4)の代わりにメソッドの矢印機能を使用してください。
これはメソッドではありませんが、プロトタイプの一部ではないため、クラスを継承しても継承されません。

+0

私はコールバックの問題として私の問題を考えていたが、これは重複した質問であることがわかっただろう。私は以前これに遭遇していないことに驚いています。 継承されていないタイプの関数のプロパティに関する追加のコメントをありがとう。それは非常に便利です。私はオプション4を選ぶ! – wolfhoundjesse

関連する問題