我正在玩Angular2。作为基础,我用了 快速开始 项目来自 angular.io 页。
一切似乎工作正常,但一旦我尝试注入服务(ItemService
进入我的 AppComponent
我得到以下异常:
Token(ComponentRef)实例化期间出错! ORIGINAL ERROR:无法解析AppComponent的所有参数。确保它们都具有有效的类型或注释。
我在互联网上看到过类似的问题(例如,包括stackoverflow) 这个帖子),但他们似乎没有解决我的问题。有没有人知道,问题可能是什么?
我也看到了一些解决方案(例如Angular2 repo中的解决方案),它们使用了解决方案来装饰注入类 Injectable
-注解。然而,这对我来说不起作用,因为它没有定义 angular.d.ts
。我使用的是错误的版本吗?
您可以在以下Plunker中找到我的解决方案:
http://plnkr.co/edit/7kK1BtcuEHjaspwLTmsg
为了记录,您还可以在下面找到我的两个文件。请注意 app.js
来自Plunker的是我在下面的TypeScript文件中生成的JavaScript文件,例外总是相同的。
index.html
:
<html>
<head>
<title>Testing Angular2</title>
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
<script src="https://jspm.io/system@0.16.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.23/angular2.dev.js"></script>
</head>
<body>
<app></app>
<script>
System.import('js/app');
</script>
</body>
</html>
js/app.ts
:
/// <reference path="../../typings/angular2/angular2.d.ts" />
import {Component, View, bootstrap, For, If} from "angular2/angular2";
class Item {
id:number;
name:string;
constructor(id:number, name:string) {
this.id = id;
this.name = name;
}
}
class ItemService {
getItems() {
return [
new Item(1, "Bill"),
new Item(2, "Bob"),
new Item(3, "Fred")
];
}
}
@Component({
selector: 'app',
injectables: [ItemService]
})
@View({
template: `<h1>Testing Angular2</h1>
<ul>
<li *for="#item of items">
{{item.id}}: {{item.name}} |
<a href="javascript:void(0);" (click)="toggleSelected(item);">
{{selectedItem == item ? "unselect" : "select"}}
</a>
</li>
</ul>
<item-details *if="selectedItem" [item]="selectedItem"></item-details>`,
directives: [For, If, DetailComponent]
})
class AppComponent {
items:Item[];
selectedItem:Item;
constructor(itemService:ItemService) {
this.items = itemService.getItems();
}
toggleSelected(item) {
this.selectedItem = this.selectedItem == item ? null : item;
}
}
@Component({
selector: 'item-details',
properties: {
item: "item"
}
})
@View({
template: `<span>You selected {{item.name}}</span>`
})
class DetailComponent {
item:Item;
}
bootstrap(AppComponent);
提前感谢任何想法!
检查几件事: -
1)确保使用从软件包位置安装的正确版本的typescript(1.5.x)。 ()如果安装了之前版本的typescript,那么仅使用“tsc”命令可以指向环境路径中的现有(<1.5)位置。
2)确保使用 --emitDecoratorMetadata
用tsc命令标记。这是必要的,因此javascript输出为装饰器创建元数据。
3) Error - Cannot read property 'annotations' of undefined
因为 AppComponent
指令依赖于 DetailComponent
还没有定义(到同步时) __decorate(
函数运行以解决依赖关系)以及TS编译提升变量的方式 DetailComponent
然后是未定义的(下面的IIFE尚未运行)。尝试移动声明 DetailComponent
之前 AppComponent
。或者只是将其移动到另一个文件并导入它。
@Component({
selector: 'item-details',
properties: {
item: "item"
}
})
@View({
template: `<span>You selected {{item.name}}</span>`
})
class DetailComponent {
item:Item;
}
@Component({
selector: 'app',
injectables: [ItemService]
})
@View({
template: `<h1>Testing Angular2</h1>
<ul>
<li *for="#item of items">
{{item.id}}: {{item.name}} |
<a href="#" (click)="toggleSelected(item);">
{{selectedItem == item ? "unselect" : "select"}}
</a>
</li>
</ul>
<item-details *if="selectedItem" [item]="selectedItem"></item-details>`,
directives: [For, If, DetailComponent]
})
class AppComponent {
items:Item[];
selectedItem:Item;
constructor(itemService:ItemService) {
this.items = itemService.getItems();
}
toggleSelected(item) {
this.selectedItem = this.selectedItem == item ? null : item;
return false;
}
}
bootstrap(AppComponent);
编辑
如果您在遵循当前文档方面遇到问题,则从角度a26开始(截至目前) 如果有帮助,请点击此链接 因为有一些相关的变化。
检查几件事: -
1)确保使用从软件包位置安装的正确版本的typescript(1.5.x)。 ()如果安装了之前版本的typescript,那么仅使用“tsc”命令可以指向环境路径中的现有(<1.5)位置。
2)确保使用 --emitDecoratorMetadata
用tsc命令标记。这是必要的,因此javascript输出为装饰器创建元数据。
3) Error - Cannot read property 'annotations' of undefined
因为 AppComponent
指令依赖于 DetailComponent
还没有定义(到同步时) __decorate(
函数运行以解决依赖关系)以及TS编译提升变量的方式 DetailComponent
然后是未定义的(下面的IIFE尚未运行)。尝试移动声明 DetailComponent
之前 AppComponent
。或者只是将其移动到另一个文件并导入它。
@Component({
selector: 'item-details',
properties: {
item: "item"
}
})
@View({
template: `<span>You selected {{item.name}}</span>`
})
class DetailComponent {
item:Item;
}
@Component({
selector: 'app',
injectables: [ItemService]
})
@View({
template: `<h1>Testing Angular2</h1>
<ul>
<li *for="#item of items">
{{item.id}}: {{item.name}} |
<a href="#" (click)="toggleSelected(item);">
{{selectedItem == item ? "unselect" : "select"}}
</a>
</li>
</ul>
<item-details *if="selectedItem" [item]="selectedItem"></item-details>`,
directives: [For, If, DetailComponent]
})
class AppComponent {
items:Item[];
selectedItem:Item;
constructor(itemService:ItemService) {
this.items = itemService.getItems();
}
toggleSelected(item) {
this.selectedItem = this.selectedItem == item ? null : item;
return false;
}
}
bootstrap(AppComponent);
编辑
如果您在遵循当前文档方面遇到问题,则从角度a26开始(截至目前) 如果有帮助,请点击此链接 因为有一些相关的变化。
我的设置:我在Windows上运行WebStorm 10.0.2,使用TypeScript 1.5 beta(编译为ES5)和node / npm。
感谢PSL的帮助,我发现我的设置存在一些问题。 它们与代码无关,例如不是类定义等的顺序 仅仅为了记录,我想总结一下我遇到的问题。大部分都被PSL提及,但也许其他人也有同样的问题,例如:与WebStorm中的编译器相关。
以下是我遇到的问题:
即使我将WebStorm配置为使用通过npm安装的TypeScript 1.5,也使用了旧版本(1.3),因为它也安装在我的系统上(我认为与Visual Studio一起)并在 %path%
变量
我将WebStorm配置为使用TypeScript的“自定义编译器版本”(在设置/语言和框架/ TypeScript中),具有以下参数: -emitDecoratorMetadata -m commonjs -t es5 -sourceMap
。这有些怎么行不通..我不确定,如果它与WebStorm中的问题有关。没有 -emitDecoratorMetadata
标志它编译,但 injectables
没用。
[更新,2015年6月9日:是的,它与a有关 问题 在WebStorm]
但是我需要 -emitDecoratorMetadata
-flag为了 injectables
在Angular2中工作。
我的解决方案是在WebStorm中添加一个自定义的“文件监视器”(而不是使用“内置编译器”功能),并带有以下参数: -emitDecoratorMetadata -m commonjs -t es5 --sourceMap $FilePath$
使用Angular2,TypeScript 1.5和WebStorm时学到的经验教训:
确保TypeScript 1.5实际上是用于编译ts文件的版本(例如,在IDE中)。
确保 -emitDecoratorMetadata
已指定。
如果按特定顺序或在自己的文件中定义类,则没有区别。 - >订单确实很重要!将类/组件拆分成不同的文件可以解决问题,并且通常会产生更好的可维护文件。
再次感谢PSL的宝贵意见!