无法解析 angular5 中的类型文档

Sun*_*arg 14 angular angular5

我想通过单击body标签上的按钮动态添加一个 CSS 类。所以我使用DOCUMENTangular的对象。这是代码

import { DOCUMENT } from "@angular/platform-browser";

... component code

constructor( @Inject(DOCUMENT) private document: Document) { }

addClass() {
    this.document.body.classList.add("any_class");
}
Run Code Online (Sandbox Code Playgroud)

但这显示错误

Metadata collected contains an error that will be reported at runtime: Could not resolve type Document.
[0]   {"__symbolic":"error","message":"Could not resolve type","line":50,"character":53,"context":{"typeName":"Document"}}
[0]     at \node_modules\@angular\compiler-cli\src\metadata\collector.js:664:27
[0]     at Array.forEach (<anonymous>)
[0]     at validateMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:652:42)
[0]     at MetadataCollector.getMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:507:17)
[0]     at LowerMetadataCache.getMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:264:39)
[0]     at LowerMetadataCache.ensureMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:209:27)
[0]     at LowerMetadataCache.getRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:204:21)
[0]     at ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:146:36
[0]     at ProjectPath\node_modules\typescript\lib\typescript.js:2601:86
[0]     at reduceLeft (ProjectPath\node_modules\typescript\lib\typescript.js:2274:30)
error Command failed with exit code 2.
[0]     at ChildProcess.exithandler (child_process.js:275:12)
[0]     at emitTwo (events.js:126:13)
[0]     at ChildProcess.emit (events.js:214:7)
[0]     at maybeClose (internal/child_process.js:925:16)
[0]     at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
Run Code Online (Sandbox Code Playgroud)

问题是什么?我正在使用angular5。还有其他方法可以动态添加类吗?

cri*_*mbo 22

如果使用类似的东西,你会得到这个错误

@Inject(DOCUMENT) document: Document
Run Code Online (Sandbox Code Playgroud)

将 tsconfig.json 中的编译器设置设置为

"angularCompilerOptions": {
  "strictMetadataEmit": true
}
Run Code Online (Sandbox Code Playgroud)

事实证明,angular 编译器Document在计算可注入参数的元数据时并不理解类型,即使它理解注入标记DOCUMENT,而 Typescript 理解 type Document

这在此处记录:https : //github.com/angular/angular/issues/20351

我使用的解决方法是:

@Injectable({
  providedIn: 'root'
})
class MyService {

  constructor(@Inject(DOCUMENT) document?: any) {
    this._document = document as Document;
  }

  private _document?: Document;

...
Run Code Online (Sandbox Code Playgroud)

any用于注入签名(使 angular 快乐),但在类中为您提供 Typescript 类型。


注意:在 Angular 9 或更高版本上,这不再是 Ivy 的问题。你可以只使用:

constructor(
  @Inject(DOCUMENT) readonly document: Document
) {}
Run Code Online (Sandbox Code Playgroud)


Gui*_*het 5

您可以在组件的装饰器之前添加“/** @dynamic */”:

/** @dynamic */
@Component({
Run Code Online (Sandbox Code Playgroud)

抑制此处提到的错误https://github.com/angular/angular/issues/20351#issuecomment-344009887和此处https://angular.io/guide/aot-compiler#strictmetadataemit