Внедренный сервис не определен в производном классе, если инициализирована закрытая переменная (Angular 2, TypeScript) - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть следующие классы:

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());
  }

}

До 17.04.2020 все работало и работало нормально, но после переустановки всех модулей npm 17.04. 2020, вызов loadAnimationInfo начал прерываться с ошибкой: Cannot read property 'show' of undefined. Звонок loadChunk все еще работал нормально, хотя. Что помогло, так это добавление вызова супер-конструктора к 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());
  }

}

Мне бы очень хотелось узнать, что может быть логика c за этим поведением?

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: все другие внедренные службы также были неопределенными в AnimatonsService

UPD3: мне удалось выяснить, что это была инициализированная частная переменная, которая сломала все. AnimationsServer на самом деле выглядит так:

export class AnimationsService extends LoaderService {

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

, что приводит к следующему коду в JS:

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

и (для меня это пока загадка!) К следующему определению в 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;
}});

Никаких зависимостей не вводится!

Если я удаляю инициализацию переменной (но я все еще могу оставить объявление private _running:Boolean;), JS результат выглядит по-разному:

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

, так же как и определение:

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;
}});

Надеюсь, это поможет пролить свет.

1 Ответ

0 голосов
/ 23 апреля 2020

это кажется известной ошибкой

Кто-то предлагает обходной путь, но это приводит к большим пакетам

, изменяя свойство compilerOptions.target на es5 в tsconfig. json

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...