使用TypeScript 1.5进行Angular 2服务注入

时间:2015-06-19 20:00:07

标签: javascript dependency-injection annotations angular typescript1.5

我试图为Angular 2设置一个非常基本的功能结构。它只有最基本的API元素,因此随着框架的发展,我可以推进我的结构。

目前,我已经知道如何执行传递服务的简单行为。以下是一些示例源代码,直接来自最新的DefinitelyTyped文件的注释:

class Greeter {
    greet(name: string) {
        return 'Hello ' + name + '!';
    }
}
@Component({
    selector: 'greet',
    appInjector: [Greeter]
})
@View({
    template: `{{greeter.greet('world')}}!`
})
class HelloWorld {
    greeter: Greeter;
    constructor(greeter: Greeter) {
        this.greeter = greeter;
    }
}
bootstrap(HelloWorld);

如您所见,我在此示例中使用了Typescript 1.5。

我尝试使用GreetinghostInjectorinjectibles在组件注释中注入appInjector服务。我也尝试将其添加到引导调用的第二个参数中,如bootstrap(HelloWorld, [Greeter])中所示。

在所有情况下,我都会在尝试在浏览器中运行时收到此错误消息:

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

当然,如果我从构造函数中删除greeter: Greeter参数,那么有问题的错误就会消失,并被链中的其他预期错误所取代。

想法?

修改

我更新了此问题的标题,以指定我使用的是TypeScript 1.5

6 个答案:

答案 0 :(得分:2)

当使用typescript 1.5.0-beta和angular 2.0.0-alpha.28(不确定版本是否严格相关)和gulp时,我遇到了类似的问题。

您需要告诉typescript编译器导出元数据,以便DI注入器知道该怎么做。我通过将emitDecoratorMetadataexperimentalDecorators添加到我的tsconfig.json:

来完成此操作
{
    "compilerOptions": {
        "module": "commonjs",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "target": "es5"
    }
}

之后,你可以像你所做的那样将appInjector: [Greeter]添加到@Component声明中,或者添加到bootstrap声明中:

bootstrap(HelloWorld, [Greeter]);

答案 1 :(得分:1)

关于TS2348。我得到了同样的错误。摆脱了ComponentAnnotaion和ViewAnnotation,这有助于:

import {
  bootstrap,
  Component,
  View
} from 'angular2/angular2';

答案 2 :(得分:1)

我希望你的代码在typescript 1.5版本中运行良好。现在,您应该在typescript 1.5.0-beta中使用Inject annotation。

import {
  ComponentAnnotation as Component,
  ViewAnnotation as View, bootstrap,
  Inject
} from 'angular2/angular2';

@Component({
  selector: 'app',
  hostInjector: [Service]
})
@View({
  template: '{{greeting}} world!'
})
class App {
  constructor(@Inject(Service)service: Service) {
    this.greeting = service.greeting();
    setTimeout(() => this.greeting = 'Howdy,', 1000);
  }
}

class Service {
  greeting() {
    return 'Hello';
  }
}

bootstrap(App);

答案 3 :(得分:0)

以下是代码,直接用于注入服务的http://plnkr.co/edit/m5sHWWFmgYPrfsMv0u2r

plnkr.co模板
import {
  ComponentAnnotation as Component,
  ViewAnnotation as View, bootstrap
} from 'angular2/angular2';

@Component({
  selector: 'app',
  viewInjector: [Service]
})
@View({
  template: '{{greeting}} world!'
})
class App {
  constructor(service: Service) {
    this.greeting = service.greeting();
    setTimeout(() => this.greeting = 'Howdy,', 1000);
  }
}

class Service {
  greeting() {
    return 'Hello';
  }
}

bootstrap(App);

答案 4 :(得分:0)

更多解决方法而不是解决方案,但是如果将服务定义移动到单独的文件(greeting.ts),并将其导入

import {Greeting} from 'greeting';

然后注射器正常工作。这是使用命令行中的tsc构建的(取自angular.io上的5分钟快速入门)

tsc --watch -m commonjs -t es5 --emitDecoratorMetadata  app.ts

答案 5 :(得分:0)

使用angular2.0.0-alpha.32,我用

完成了这个
/// <reference path="../../typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
import {MyService} from 'js/services/MyService';

// Annotation section
@Component({
    selector: 'my-app',
    viewInjector: [MyService]
})
@View({
    templateUrl: 'templates/my-app.tpl.html',
    directives: [NgFor]
})

class MyComponent {
    mySvc:MyService;

    constructor(mySvc:MyService) {
        this.mySvc = mySvc;
    }

    onInit() {
        this.mySvc.getData();
    }
}   

bootstrap(MyComponent, [MyService]);