Angular组件在转换过程中丢失了元数据

时间:2017-08-07 06:22:44

标签: angular typescript decorator angular2-decorators

再来一次: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

预期行为

添加使用相同polyfill的外部库不必导致错误。

使用说明书轻微复制问题

错误描述:有两个组成部分:

AppComponent和UserDialogComponent

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

之前有效

有错误的回购:https://github.com/k1r0s/angular2-aop-showcase/ 分支:iss-angular-reflection 重现的步骤:克隆repo,git checkout origin / iss-angular-reflection,npm install,ng serve

aditional info(带有错误跟踪的图片): http://imgur.com/a/Yz2qu

附加图片:如果您设置了“暂停异常”,则使用Chrome开发工具,然后在callstack上进行两次然后评估:meta.declarations[1]您应该获取UserDialogComponent构造函数引用,然后您可以执行: Reflect.getMetadata("annotations", meta.declarations[1]) 为了检索组件元数据,但它返回undefined而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

谢谢!

1 个答案:

答案 0 :(得分:0)

正如@yurzui指出的那样,reflect-metadata包会覆盖全局引用,因此它与例如core-js冲突。

在我的情况下,solition是替换reflect-metadata的{​​{1}}包,然后在我的构建中包含来自core-js的作用域polyfill反射。

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