Angular 通用:MouseEvent 未定义

Angular Universal: MouseEvent is not defined

我是 运行 命令 dev:ssr 并在我的 Angular 10 项目中得到以下异常:

Compiled successfully.
./dist/Project/server/main.js:220253
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [MouseEvent]), 

ReferenceError: MouseEvent is not defined

我知道像 win/document/etc. is undefined 这样的消息也存在类似的问题,但是,这些问题的解决方案对我不起作用。

我尝试使用 isPlatformBrowser() 并使用 domino 模拟浏览器行为,但是没有效果。

我的 ng 版本:


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 10.2.0
Node: 12.19.0
OS: darwin x64

Angular: 10.2.0
... animations, cli, common, compiler, compiler-cli, core, forms
... localize, platform-browser, platform-browser-dynamic
... platform-server, router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.1002.0
@angular-devkit/build-angular      0.1002.0
@angular-devkit/build-ng-packagr   0.1002.0
@angular-devkit/core               10.2.0
@angular-devkit/schematics         10.2.0
@angular/cdk                       10.2.5
@angular/fire                      5.4.2
@angular/flex-layout               10.0.0-beta.32
@angular/material                  10.1.3
@angular/material-moment-adapter   10.2.5
@nguniversal/builders              10.1.0
@nguniversal/express-engine        10.1.0
@schematics/angular                10.2.0
@schematics/update                 0.1002.0
ng-packagr                         10.1.2
rxjs                               6.6.3
typescript                         3.9.7

还有其他想法吗?

更新:

其中一个使用了 MouseEvent 的库出现了 2 次。

第一个如下(需要检测用户是否在组件外部点击,关闭它):

  @HostListener('document:click', ['$event'])
  clickedOutside(event: MouseEvent) {
    const clickedInside = this.innerClasses.some(innerClass => (event.target as HTMLElement).classList.contains(innerClass));
    if (!this.eRef.nativeElement.contains(event.target) && !clickedInside) {
      this.closeDialog();
    }
  }

另一种是重点输入:

  onContainerClick(event: MouseEvent) {
    if ((event.target as Element).tagName.toLowerCase() !== 'input') {
      this.elRef.nativeElement.querySelector('input').focus();
    }
  }

正如我所提到的,我已经尝试使用 isPlatformBrowser(),但是,它没有任何效果,而且我仍然看到该错误消息。

我检查了你的代码。
不建议通过直接访问 DOM 来绕过 Angular。出于这个特定原因,您会遇到 SSR 问题。尽可能使用数据绑定和事件绑定。
对于这个用例,您不能使用事件绑定而不是 @hostListener 吗?

如果你不能这样做,至少使用 renderer2 服务来访问 DOM (https://angular.io/api/core/Renderer2)。不要直接使用 nativeElement。 它还将帮助您保护您的应用免受 cross-site 脚本攻击。
也忘记 .querySelector() 来请求 dom 元素。请改用 @ViewChild