4

我正在尝试为 Angular 2 设置一个非常基本的功能结构。它将只有最基本的 API 元素,以便随着框架的进步,我可以改进我的结构。

目前,对于如何执行传递服务的简单行为,我束手无策。下面是一些示例源代码,取自最近的 ExplainedTyped 文件的注释:

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。

我尝试使用 和 将服务注入到组件Greeting注释hostInjector中。我还尝试将它添加到引导调用的第二个参数中,如.injectiblesappInjectorbootstrap(HelloWorld, [Greeter])

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

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

当然,如果我greeter: Greeter从构造函数中删除参数,则相关错误就会消失,并被其他预期的错误所取代。

想法?

编辑

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

4

6 回答 6

2

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

您需要告诉 typescript 编译器导出元数据,以便 DI 注入器知道该做什么。我通过在我的 tsconfig.json中添加emitDecoratorMetadata和来做到这一点:experimentalDecorators

{
    "compilerOptions": {
        "module": "commonjs",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "target": "es5"
    }
}

之后,您可以像您所做的那样添加appInjector: [Greeter]到您的声明或引导程序声明中:@Component

bootstrap(HelloWorld, [Greeter]);
于 2015-06-28T17:09:11.067 回答
1

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

import {
  bootstrap,
  Component,
  View
} from 'angular2/angular2';
于 2015-06-21T19:42:44.923 回答
1

我希望您的代码在 typescript 1.5 版本中可以正常工作。现在,您应该在 typescript 1.5.0-beta 中使用 Inject 注释。

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);
于 2015-07-07T05:16:17.337 回答
0

这是直接来自 plnkr.co 模板的代码,用于注入服务http://plnkr.co/edit/m5sHWWFmgYPrfsMv0u2r

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);
于 2015-06-19T22:14:08.293 回答
0

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

import {Greeting} from 'greeting';

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

tsc --watch -m commonjs -t es5 --emitDecoratorMetadata  app.ts
于 2015-07-01T09:28:20.817 回答
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]);
于 2015-07-29T22:33:32.950 回答