【问题标题】:Angular 2 service injection using TypeScript 1.5使用 TypeScript 1.5 的 Angular 2 服务注入
【发布时间】:2015-09-05 22:07:19
【问题描述】:

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

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

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。

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

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

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

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

想法?

编辑

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

【问题讨论】:

  • 您找到解决方案了吗?
  • 还没有。错误仍然发生。我仍然想知道这是否是类型定义问题。

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


【解决方案1】:

这是直接来自 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);

【讨论】:

  • 它使用的是哪个版本的 Angular 2?能否提供 plnkr 的链接?
  • 将其添加到答案中
  • 这确实可以在 plunker 中使用,但它不适用于 TypeScript 1.5。我得到的第一个错误是 TS2348 “typeof ComponentAnnotation”类型的值不可调用。您的意思是要包含“新”吗? 这可能是打字问题吗?请注意,我在文件前面添加了一个 ///reference path,它指向最新的 ExplainedTyped angular2.d.ts 文件。
  • 仅供任何正在阅读本文的人参考...... hostInjector 和 viewInjector 不再在 Angular 2 中。他们最后一次提到的是 Angular 2 Alpha 版本 31 的更改日志。
【解决方案2】:

我希望您的代码在 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);

【讨论】:

  • 仅供任何正在阅读本文的人参考...... hostInjector 和 viewInjector 不再在 Angular 2 中。他们最后一次提到的是 Angular 2 Alpha 版本 31 的更改日志。
【解决方案3】:

使用 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]);

【讨论】:

  • 仅供任何正在阅读本文的人参考... hostInjector 和 viewInjector 不再在 Angular 2 中。他们最后一次提到的是 Angular 2 Alpha 版本 31 的更改日志
【解决方案4】:

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

import {Greeting} from 'greeting';

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

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

【讨论】:

  • 感谢 Paul,但该解决方案对我不起作用。我用appInjectorhostInjector@ComponentviewInjector@View 以及bootstrap(HelloWorld, [Greeter]) 尝试了它。你在使用 Angular 2.0.0-alpha.28 和 TypeScript 1.5.0-beta 吗?另外,为了确认一下,我的示例中的服务是Greeter。主引导对象是HelloWorld。你真的是这个意思吗?
  • @PeteGardner 已验证我的版本与您的版本相同,并更新了我的答案以(希望)澄清一下。
【解决方案5】:

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

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

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

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

bootstrap(HelloWorld, [Greeter]);

【讨论】:

  • 这看起来很有希望。一旦我能够让 Visual Studio 2015 RC 接受这些值,我会告诉你它是否对我有用。
【解决方案6】:

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

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

【讨论】:

  • 谢谢,摆脱了 TS2348 错误,但产生了与上述相同的错误。你在使用 Angular 2.0.0-alpha.27 吗?打字稿 1.5?
猜你喜欢
  • 2018-05-20
  • 2017-08-24
  • 2016-08-08
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
  • 2017-08-14
  • 2016-11-24
相关资源
最近更新 更多