简体   繁体   English

如果私有变量已初始化(Angular 2,TypeScript),则在派生的 class 中未定义注入服务

[英]Injected service is undefined in derived class if private variable is initialized (Angular 2, TypeScript)

I have the following classes:我有以下课程:

import {Http, Response} from "@angular/http";
import {ErrorService} from "./error.service";
import {PreloaderService} from "./preloader.service";
import {Observable} from "rxjs/Observable";

@Injectable()
export class LoaderService {

  constructor(protected http: Http,
              protected errorService: ErrorService,
              protected preloaderService: PreloaderService) {}

  private sendPost(url: string, body: any): Observable<Response> {
    this.preloaderService.show();
    return this.http.post(url, body)
      .map((r: Response): Response => {
        this.preloaderService.hide();
        return r;
      })
      .catch((e: any): any => this.errorService.handleError(e));
  }

}
import {LoaderService} from "./loader.service";

@Injectable()
export class CollectionService extends LoaderService {

  loadChunk(params: ILoaderParams) {
    return this.sendPost(params.createEndpointUrl("/loadChunk"), params.getBody())
      .map(r => <ILoadChunkResult>r.json());
  }

}
import {LoaderService} from "./loader.service";

@Injectable()
export class AnimationsService extends LoaderService {

  loadAnimationInfo(ownerId: string, ownerType: string): Observable<IAnimationInfo> {
    const body = { ownerId, ownerType };
    return this.sendPost("/animations/load-info", body)
      .map(r => <IAnimationInfo>r.json());
  }

}

Until 17.04.2020 it was all building and working fine, but after I've reinstalled all npm modules on 17.04.2020, calling loadAnimationInfo started to break with an error: Cannot read property 'show' of undefined .直到 17.04.2020 一切都在构建和工作正常,但是在我在 17.04.2020 上重新安装了所有 npm 模块后,调用loadAnimationInfo开始因错误而中断: Cannot read property 'show' of undefined Calling loadChunk was still working fine though.调用loadChunk仍然可以正常工作。 What helped was to add super constructor call to AnimationsService :有帮助的是向AnimationsService添加超级构造函数调用:

import {LoaderService} from "./loader.service";
import {Http} from "@angular/http";
import {ErrorService} from "./error.service";
import {PreloaderService} from "./preloader.service";

@Injectable()
export class AnimationsService extends LoaderService {

  constructor(protected http: Http,
              protected errorService: ErrorService,
              protected preloaderService: PreloaderService) {
    super(http, errorService, preloaderService);
  }

  loadAnimationInfo(ownerId: string, ownerType: string): Observable<IAnimationInfo> {
    const body = { ownerId, ownerType };
    return this.sendPost("/animations/load-info", body)
      .map(r => <IAnimationInfo>r.json());
  }

}

I would really like to know what could be the logic behind this behaviour?我真的很想知道这种行为背后的逻辑是什么?

UPD:升级版:

import {Injectable} from "@angular/core";
import {BusService} from "./bus.service";

@Injectable()
export class PreloaderService {
  private requestCount: number = 0;
  constructor(private busService: BusService) {
  }
  show() {

    if (this.requestCount > 0) {
      return;
    }
    this.requestCount++;
    this.busService.emitPreloaderIsVisible(true);
  }


  hide() {
    this.requestCount--;
    if (this.requestCount > 0) {
      return;
    }
    this.requestCount = 0;
    this.busService.emitPreloaderIsVisible(false);
  }
}

UPD2: all other injected services were as well undefined in the AnimatonsService UPD2:所有其他注入的服务在AnimatonsService中也未定义

UPD3: i've managed to figure out, that it was an initialized private variable, that broke everything. UPD3:我设法弄清楚,这是一个初始化的私有变量,它破坏了一切。 AnimationsServer actually looks like: AnimationsServer 实际上看起来像:

export class AnimationsService extends LoaderService {

  private _running:boolean = true;//it was not used, so I didnt pay attention on it at first
  ...
}

which leads to the following code in JS:这导致JS中的以下代码:

function AnimationsService() {
    var _this = _super !== null && _super.apply(this, arguments) || this;
    _this._running = true;
    return _this;
}

and (this is still a mystery to me!) to the following definition in the module.ngfactory.js :并且(这对我来说仍然是个谜!)到module.ngfactory.js中的以下定义:

Object.defineProperty(AppModuleInjector.prototype, '_AnimationsService_79', { get: function() {
  var self = this;
  if ((self.__AnimationsService_79 == null)) { (self.__AnimationsService_79 = new jit_AnimationsService97()); }
  return self.__AnimationsService_79;
}});

No dependencies are injected!没有依赖注入!

If I remove the initialization of the variable (but I still can leave the declaration private _running:Boolean; ), the JS result looks different:如果我删除变量的初始化(但我仍然可以保留声明private _running:Boolean; ),JS 结果看起来不同:

function AnimationsService() {
    return _this = _super !== null && _super.apply(this, arguments) || this;
}

and so is the definition:定义也是如此:

Object.defineProperty(AppModuleInjector.prototype, '_AnimationsService_79', { get: function() {
  var self = this;
  if ((self.__AnimationsService_79 == null)) { (self.__AnimationsService_79 = new jit_AnimationsService97(self._Http_57,self._ErrorService_66,self._PreloaderService_65)); }
  return self.__AnimationsService_79;
}});

Hope this will help to bring some light.希望这将有助于带来一些光明。

it seem a known bug这似乎是一个已知的错误

Someone suggest a workaround but it leads to bigger bundles有人提出了一种解决方法,但它会导致更大的捆绑包

changing the compilerOptions.target property to es5 in tsconfig.json在 tsconfig.json 中将 compilerOptions.target 属性更改为 es5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM