Angular2

时间:2015-05-18 19:38:38

标签: angular typescript

我正在玩Angular2。作为基础,我使用了quickstart页面中的angular.io项目。

一切似乎都运行良好,但是一旦我尝试将服务(ItemService)注入我的AppComponent,我就会遇到以下异常:

  

Token(ComponentRef)实例化期间出错! ORIGINAL ERROR:无法解析AppComponent的所有参数。确保它们都有有效的类型或注释。

我在互联网上看到过类似的问题(包括stackoverflow,例如this post),但它们似乎都没有解决我的问题。有没有人知道,问题可能是什么?

我还看到了一些解决方案(例如Angular2 repo中的解决方案),它使用Injectable注释来装饰注入类。然而,这对我来说并不起作用,因为它没有在angular.d.ts中定义。我使用的是错误的版本吗?

您可以在以下Plunker中找到我的解决方案: http://plnkr.co/edit/7kK1BtcuEHjaspwLTmsg

为了记录,您还可以在下面找到我的两个文件。请注意,Plunker中的app.js是我在下面的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);

提前感谢任何想法!

3 个答案:

答案 0 :(得分:11)

检查几件事: -

1)确保使用从软件包位置安装的正确版本的typescript(1.5.x)。 ()如果您安装了以前版本的打字稿,那么仅使用&#34; tsc&#34;命令可以指向环境路径中的现有(&lt; 1.5)位置。

2)确保在tsc命令中使用--emitDecoratorMetadata标志。这是必要的,因此javascript输出会为装饰器创建元数据。

3)Error - Cannot read property 'annotations' of undefined  因为AppComponent指令依赖于DetailComponent尚未定义(当同步__decorate(函数运行以解析依赖关系时)以及TS编译提升变量的方式{{ 1}}未定义(下面的IIFE尚未运行)。尝试在DetailComponent之前移动DetailComponent的声明。或者只是将其移动到另一个文件并导入它。

AppComponent

修改

如果您在遵循当前文档(截至目前)follow this link if it helps时遇到问题,则角度为a26,因为存在一些相关更改。

答案 1 :(得分:3)

我的设置:我在Windows上运行WebStorm 10.0.2,使用TypeScript 1.5 beta(编译为ES5)和node / npm。

感谢PSL的帮助,我发现我的设置存在一些问题。 它们与代码无关,例如不是类定义的顺序等等。为了记录,我想总结一下我遇到的问题。大部分都被PSL提及,但也许其他人有同样的问题,例如与WebStorm中的编译器相关。

以下是我遇到的问题:

  • 即使我将WebStorm配置为使用通过npm安装的TypeScript 1.5,也使用了旧版本(1.3),因为它也安装在我的系统上(我想与Visual Studio一起)并在{{ 1}}变量

  • 我将WebStorm配置为使用&#34;自定义编译器版本&#34;对于TypeScript(在settings / Languages和Frameworks / TypeScript中),使用以下参数:%path%。这有些不起作用..我不确定,如果它与WebStorm中的问题有关。没有编译-emitDecoratorMetadata -m commonjs -t es5 -sourceMap标记,但-emitDecoratorMetadata没有工作。

    [更新,2015年6月9日:是的,它与WebStorm中的issue相关]

  • 但是我需要injectables - 标志,以便Angular2中的-emitDecoratorMetadata能够正常工作。

  • 我的解决方案是添加一个自定义&#34;文件观察器&#34;在WebStorm中(而不是使用&#34;内置编译器&#34; -function)具有以下参数:injectables

使用Angular2,TypeScript 1.5和WebStorm时的经验教训:

  • 确保TypeScript 1.5确实是用于编译ts文件的版本(例如,在IDE中)。

  • 确保指定了-emitDecoratorMetadata -m commonjs -t es5 --sourceMap $FilePath$

  • 如果按特定顺序或自己的文件等定义类,则没有区别。 - &gt;订单确实很重要!将类/组件拆分为不同的文件可以解决问题,并且通常会产生更好的可维护文件。

再次感谢PSL的宝贵意见!

答案 2 :(得分:2)

我遇到了同样的问题。以下是决议:

  1. - 在tsc
  2. 中错过了emitDecoratorMetadata
  3. 如果我从同一个文件注入服务它失败了,但是当我把服务放到其他文件时,当它被导入时,它就开始工作了。可能是我使用的Angular2版本中的错误。