【问题标题】:Uncaught (in promise): TypeError: token is undefinedUncaught (in promise): TypeError: token is undefined
【发布时间】:2020-02-04 11:14:45
【问题描述】:

我有一个 Angular 8 应用程序并且在开发模式下运行良好,但是如果我执行 'ng serve --prod' 它正在编译而没有错误但是在启动应用程序时我在控制台中遇到了这个错误:

ERROR 错误:“未捕获(在承诺中):TypeError:令牌未定义 getOrCreateInjectable/bloomHashhttp://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:249524 getOrCreateInjectable@http://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:249614 获取@http://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:254632 播放器组件@http://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:726594 工厂@http://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:728189 getNodeInjectable@http://localhost:4200/main.cf6fe5006f05f980ad3b.js:1:253710 ...

您知道如何确定问题所在吗? 读取错误我调用了我的 PlayerComponent 但没有什么特别的

import { Game, IsoScene } from 'src/app/tars/classes';
import { NavigatorService } from 'src/app/tars/services';
import { DataProvider, ElementProvider } from 'src/app/tars/providers';
import { ElementProvider as POCElementProvider } from 'src/app/services/element.provider';
import { IsoPlayerScene } from 'src/app/classes/scenes/iso';
import { InteractionsMenu } from 'src/app/interfaces';
import { DataProviderFactory } from 'src/app/services/dataProviders/factory.service';
import { OnReadyRenderer2DEvent, Interaction } from 'src/app/tars/interfaces';
import { TitleScene } from 'src/app/classes/scenes/title';

@Component({
  selector: 'tars-player',
  templateUrl: './player.component.html',
  styleUrls: ['./player.component.scss']
})
export class PlayerComponent {
  private rendererW: number;
  private rendererH: number;

  public get rendererHeight(): number {
    return this.rendererH;
  }

  public get rendererWidth(): number {
    return this.rendererW;
  }

  private game: Game;
  private navigatorService: NavigatorService;
  private dataProvider: DataProvider;
  private elementProvider: ElementProvider;

  private isoPlayer: IsoPlayerScene;
  public menuStructure: InteractionsMenu;

  constructor(
    private injector: Injector,
    private ngZone: NgZone
  ) {
    this.navigatorService = injector.get(NavigatorService);

    this.dataProvider = injector.get(DataProvider);
    this.dataProvider.set(injector.get(DataProviderFactory.factory()));

    this.elementProvider = injector.get(ElementProvider);
    this.elementProvider.set(injector.get(POCElementProvider));

    this.resetInteractionsMenu();
  }

  rendererOnReady(event: OnReadyRenderer2DEvent) {
    // Create the game object
    this.game = new Game(this.injector, event.context);
    this.game.onLoaded.subscribe((res: boolean) => {
      // Ask current client size
      this.refreshClientSize();
      // Run the game (when ready inside)
      this.ngZone.runOutsideAngular(() => this.game.run());
    });

    // Specific link
    this.isoPlayer = new IsoPlayerScene(this.injector, {name: 'world'}, event.context);
    this.isoPlayer.onInteractionsMenu.subscribe((structure: InteractionsMenu) => {
      this.ngZone.run(() => {
        if (structure) {
          this.menuStructure = structure;
        } else {
          this.resetInteractionsMenu();
        }
      });
    });

    this.game.load([
      this.isoPlayer,
      new TitleScene(this.injector, {name: 'title'}, event.context),
      new IsoScene(this.injector, {name: 'loader'}, event.context),
    ], 'title', 'loader');
  }

  // Listen the window resize event
  @HostListener('window:resize', ['$event'])
  onResize(event: any) {
    this.refreshClientSize();
    this.resetInteractionsMenu();
  }

  // Get the window/body size to set the graph size
  public refreshClientSize() {
    const browserSize = this.navigatorService.getClientSizeFromBrowser();
    this.rendererW = browserSize.width;
    this.rendererH = browserSize.height;
    this.navigatorService.setClientSize(browserSize.width, browserSize.height);
  }

  // Keyboard management
  @HostListener('window:keydown', ['$event'])
  onKeyPress(event: any) {
    this.navigatorService.keyDown(event);
  }

  private resetInteractionsMenu() {
    this.menuStructure = {
      interactions: [],
      screenCoord: { screenX: 0, screenY: 0 }
    };
  }

  // Do interaction when menu selection is done and reset menu
  menuOnSelect(interaction: Interaction) {
    this.isoPlayer.doInteraction(interaction);
    this.resetInteractionsMenu();
  }
}

就像我说的,它在 dev 中工作,我不明白为什么 --prod 会给出这个结果。

编辑:

这似乎是关于工厂的this.dataProvider.set(injector.get(DataProviderFactory.factory())); 行,下面的代码在--prod 上中断

@Injectable()
export class DataProviderFactory {
  public static factory() {
    if (environment.dataOrigin === DataOrigin.Fake) {
      return Faker;
    } else {
      // ...
    }
  }
}

如果我直接用 Faker 替换 DataProviderFactory.factory(),它就可以工作。 我读到了 Ivy 和 creatInjector 的一些问题,但它似乎不起作用。

有什么想法吗?

【问题讨论】:

  • 使用 ng build --prod --optimizer 创建一个构建,你会得到你得到错误的确切位置
  • 对我来说,错误来自bloomHash,但不确定。试试上面的评论,看看你能不能得到更多的细节。
  • 使用 '$ ng build --prod --optimization' 我收到了 3 个关于未使用文件(如 env.prod.ts)的警告,但没有更多详细信息。
  • 问题已编辑详细,谢谢

标签: angular typescript angular8


【解决方案1】:

在 --prod 的上下文中,DataProviderFactory 返回一个空值,注入器无法处理标记化。所以它失败了,我的错。但是显示的异常一点也不清晰和有帮助。希望这可以帮助其他人。

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 2021-01-08
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多