做我们的第一个大应用程序我们遇到了一个应该在typescript 2.0 +
中修复的问题拥有Abstract类:
export abstract class HttpBaseService {
protected abstract readonly TAG: any;
protected abstract _state: GlobalState;
private r = Math.random();
protected extractData(res: Response) {
console.log(`${this.TAG}:extractData:`, res.json());
const data = res.json() || [];
return data;
}
protected handleErrors(error: Response) {
console.error(`${this.TAG}:handleErrors:`, error);
console.log(this.TAG);
console.log(this._state);
if (error.status === 401 || error.status === 403) {// Not Authorized
console.error(`${this.TAG}:handleErrors: NOT AUTHORIZED`, error);
this._state.notifyDataChanged("logout", error);
}
return Observable.throw(error.json());
}
}
和实施:
@Injectable()
export class AlbumService extends HttpBaseService {
TAG = AlbumService.name;
constructor(protected _state: GlobalState,
private http: Http,
private auth: AuthService,
private localStorage: LocalStorageService,) {
super();
this._state = _state;
}
albums() {
console.log(`${this.TAG}:albums:`);
console.log(this._state);
const ALBUMS_URL = this.albumsUrl();
const token = this.auth.getToken();
const headers = new Headers();
headers.append('Authorization', `Token ${token}`);
return this.http
.get(`${Constants.API_URL}${ALBUMS_URL}`, {headers})
.catch(this.handleErrors)
.map(this.extractData);
}
}
当超类中的函数handleError在子类中执行时,参数TAG和_state都为"未定义"
请注意,我测试了它将它从构造函数中抽象,保护,公开,手动分配成员,以及其他几个。
我必须遗漏一些东西,因为在子类构造函数中,我尝试在分配_state之后调用handleError方法并且它按预期工作,具有TAG的值和_state的值。
更新:将问题减少到最小化
现在我有:
export abstract class HttpBaseService {
protected abstract _state: GlobalState;
protected handleErrors(error: Response) {
console.log(this._state);
}
protected extractData(res: Response) {
const data = res.json() || [];
return data;
}
}
和实施:
@Injectable()
export class AlbumService extends HttpBaseService {
constructor(_state: GlobalState,
private http: Http,
private auth: AuthService,
private localStorage: LocalStorageService,) {
super();
this._state = _state;
}
albums() {
const token = this.auth.getToken();
const headers = new Headers();
headers.append('Authorization', `Token ${token}`);
return this.http
.get(`${Constants.API_URL}`, {headers})
.catch(this.handleErrors)
.map(this.extractData);
}
}
答案 0 :(得分:0)
从属性中删除abstract
:
protected abstract readonly TAG: any;
protected abstract _state: GlobalState;
this._state = this._state
应该是this._state = _state;
AlbumService.name
似乎没有在任何地方定义。因此,您要将未定义 this._state
分配给this._state
,并将未定义,并指定underfined
AlbumService.name
到TAG
。
答案 1 :(得分:0)
事实证明,当我将参考函数传递给.catch和.map时,这些函数被复制,并且" this"变化。
所以"这个"在Observable Subscriber的函数引用中。我不知道这是否是一个设计问题,但我花了一整天才弄明白。
所以,现在我在Super Class中的方法调用是这样的:
export abstract class HttpBaseService {
protected readonly TAG = HttpBaseService.name;
protected state: GlobalState;
protected extractData(res: Response) {
console.log(`${this.TAG}:extractData:`, res.json());
const data = res.json() || [];
return data;
}
protected handleErrors(error: Response) {
console.error(`${this.TAG}:extractData:`, error);
if (error.status === 401 || error.status === 403) {
this.state.notifyDataChanged('logout', error);
}
return Observable.throw(error.json());
}
}
我这样用过:
return this.http
.delete(`${Constants.API_URL}${ALBUMS_URL}${id}/`, {headers})
.catch((e, c) => this.handleErrors(e))
.map(res => this.extractData(res));