角度组件在转译过程中会丢失其元数据



另一个:Uncaught Error: Unexpected value 'UserDialogComponent' declared by the module 'AppModule'. Please add a @Pipe/@Directive/@Component annotation.

当前行为

摘要:包含使用reflect-metadata的外部库会导致如下错误:https://github.com/angular/angular/issues/15890

预期行为

添加使用相同填充代码的外部库不一定会导致错误。

使用指令对问题的最小再现

错误描述:有两个组件:

AppComponent 和 UserDialogComponent

正如我所看到的,UserDialogComponent的行为好像没有用@Component装饰,但事实并非如此。我认为问题依赖于反映元数据填充。如果我删除kaop-ts库添加的装饰器,一切顺利。但它在添加用户对话框组件之前有效:\

有错误的存储库:https://github.com/k1r0s/angular2-aop-showcase/分支:ISS-角度反射 重现步骤:克隆存储库,Git Checkout origin/iss-angular-reflect,npm install,ng serve

其他信息(带有错误跟踪的图像(: https://i.stack.imgur.com/zxxQH.jpg

附图: 使用 Chrome 开发工具,如果您设置了"异常时暂停",那么您会在调用堆栈上上升两次,然后评估:meta.declarations[1]您应该获取 UserDialogComponent 构造函数引用,然后您可以执行:Reflect.getMetadata("annotations", meta.declarations[1])为了检索组件元数据,但它返回未定义,而Reflect.getMetadata("annotations", meta.declarations[0])将成功返回 AppComponent 的 medatada ...这有点奇怪..

改变行为的动机/用例是什么?

通过删除第三方装饰器,Angular 组件维护其元数据

环境


Angular version: 4.0.0
package.json (project was generated with angular-cli)
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/cdk": "^2.0.0-beta.8",
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/material": "^2.0.0-beta.8",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"core-js": "^2.4.1",
"kaop-ts": "^1.4.0",
"rxjs": "^5.4.1",
"zone.js": "^0.8.14"
},
Browser:
- [x] Chromium (desktop) version `Version 59.0.3071.109 (Developer Build)` 
For Tooling issues:
- Node version: v6.11.2
- Platform: Linux

谢谢!

@yurzui指向时,反射元数据包会覆盖全局引用,因此它与例如core-js冲突。

就我而言,将reflect-metadata包替换为core-js,然后在我的构建中包含来自 core-js 的作用域填充反射。

关于为什么一个组件没有任何问题的正确解释是因为装饰器是在声明类时评估的,所以当评估角度装饰器时,评估第三方装饰器是没有痛苦的,因为javascript已经将元数据存储在内存中并且可以访问。问题出在另一个组件上,因为在声明第一个组件后,Typescript 会评估来自第三方库的以下方法装饰器,这些库通过重新分配当前全局Reflect对象来使用reflect-metadata...(污染全局命名空间..然后,Angular 尝试加载第二个组件,但@component无法再将元数据存储在需要放置的位置,因此 Angular 抱怨第二个组件没有@component声明,这在第一手资料中很烦人且奇怪。

相关内容

  • 没有找到相关文章