我在将类加载到Angular组件时遇到问题。我已经尝试解决很长时间了;我什至尝试将它们全部合并到一个文件中。我所拥有的是:

Application.ts

/// <reference path="../typings/angular2/angular2.d.ts" />

import {Component,View,bootstrap,NgFor} from "angular2/angular2";
import {NameService} from "./services/NameService";

@Component({
    selector:'my-app',
    injectables: [NameService]
})
@View({
    template:'<h1>Hi {{name}}</h1>' +
    '<p>Friends</p>' +
    '<ul>' +
    '   <li *ng-for="#name of names">{{name}}</li>' +
    '</ul>',
    directives:[NgFor]
})

class MyAppComponent
{
    name:string;
    names:Array<string>;

    constructor(nameService:NameService)
    {
        this.name = 'Michal';
        this.names = nameService.getNames();
    }
}
bootstrap(MyAppComponent);


services / NameService.ts

export class NameService {
    names: Array<string>;
    constructor() {
        this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
    }
    getNames()
    {
        return this.names;
    }
}


我不断收到一条错误消息,提示No provider for NameService

有人可以帮我发现我的代码问题吗?

评论

从Alpha 42开始:@Component({provider:[NameService]})

#1 楼

您必须使用providers而不是injectables



 @Component({
    selector: 'my-app',
    providers: [NameService]
})
 


完整的代码示例在这里。

评论


@unobf的导入语句对我来说似乎不完整。对于angular2库的旧版alpha,先前的答案可能是正确的。原始指南指的是alpha-28,我使用的是alpha35。此外,我提供了指向完整代码示例的链接,因此,我想我已经提供了很多信息。

–克拉斯·梅尔本(Klas Mellbourn)
15年8月31日在8:02

面向未来的Google员工的更新:使用提供程序可使用最新的Beta(Beta 0)。

– nathanhleung
2015年12月30日下午5:00

@nathanhleung绑定和提供程序都起作用-这是临时的还是在内部进行相同的操作

–Simon_Weaver
16年4月7日在18:04

@Simon_Weaver嗯,他们可能已在最新Beta中对其进行了更改-在beta.0中,我无法使其与绑定一起使用

– nathanhleung
16-4-7在22:51

如果该服务是从另一个服务中使用的呢?我将其添加到模块提供程序中,我认为这将使其在全球范围内可用,但仍然会收到该错误

–声波灵魂
16-10-4在15:06

#2 楼

在Angular 2中,可以在三个位置“提供”服务:

其他组件或指令

”引导程序提供程序选项用于配置和覆盖Angular自己的预注册服务,例如其路由支持。” -参考

如果只希望在整个应用程序中使用NameService的一个实例(即Singleton),则将其包含在根组件的providers数组中:

@Component({
   providers: [NameService],
   ...
)}
export class AppComponent { ... }


柱塞

如果您希望每个组件有一个实例,请在组件的配置对象中使用providers数组:

@Component({
   providers: [NameService],
   ...
)}
export class SomeOtherComponentOrDirective { ... }


有关更多信息,请参见“分层注射器”文档。

评论


这是一个很好的答案。它还进一步说明了在根组件中声明服务与在其他子组件中声明服务之间的区别。

–塔夫
17年2月7日在22:51

#3 楼

从Angular 2 Beta开始:

@Injectable添加到服务中为:

@Injectable()
export class NameService {
    names: Array<string>;

    constructor() {
        this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
    }

    getNames() {
        return this.names;
    }
}


并在组件配置中将providers添加为:

@Component({
    selector: 'my-app',
    providers: [NameService]
})


#4 楼

您应该在NameServiceproviders元数据的AppModule数组中注入NgModule

@NgModule({
   imports: [BrowserModule, ...],
   declarations: [...],
   bootstrap: [AppComponent],
   //inject providers below if you want single instance to be share amongst app
   providers: [MyService]
})
export class AppModule {

}


如果要为特定组件级别创建依赖项而又不用担心状态问题应用程序,则可以注入对组件providers元数据选项的依赖,例如显示的已接受@Klass答案。

评论


我尝试在@NgModule部分的app.module.shared.ts中添加服务:提供程序:[DataManagerService],但仍然出现错误:错误:DataManagerService没有提供程序!

– Paul
17-10-17在16:09



@Paul您是否将服务注入正确的模块? DataManagerService是否具有@Injectable装饰器?

–潘卡吉·帕卡(Pankaj Parkar)
17-10-17在16:47

#5 楼

令人震惊的是,在最新版本的Angular中,语法再次发生了变化:-)从Angular 6文档:


从Angular 6.0开始,创建单例的首选方法
服务是在服务上指定应在应用程序根目录中提供的服务。这是通过将providerIn设置为服务的@Injectable装饰器的根目录来实现的:


src / app / user.service.0.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}


#6 楼

您应该将NameService注入AppModule的NgModule元数据的provider数组内。

@NgModule({
   providers: [MyService]
})


并确保以相同的名称(区分大小写)导入组件,因为SystemJs是大小写敏感(通过设计)。如果您在项目文件中使用其他路径名,例如:

main.module.ts

import { MyService } from './MyService';


your-component.ts

import { MyService } from './Myservice';


然后System js将进行双重导入

评论


优秀的!使用桶对进口进行分组时,遇到了此错误。您的SystemJS提示帮助了我:)

–乔尼·亚当特(Jony Adamit)
17年7月10日在7:52

#7 楼

在Angular v2及更高版本中,它现在是:

@Component({ selector:'my-app', providers: [NameService], template: ... })

#8 楼

Angular 2已经更改,这是您的代码顶部的外观:

import {
  ComponentAnnotation as Component,
  ViewAnnotation as View, bootstrap
} from 'angular2/angular2';
import {NameService} from "./services/NameService";

@Component({
  selector: 'app',
  appInjector: [NameService]
})


此外,您可能希望在服务中使用getter和setter:

export class NameService {
    _names: Array<string>;
    constructor() {
        this._names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
    }
    get names() {
        return this._names;
    }
}


然后在您的应用中,您可以轻松执行以下操作:

this.names = nameService.names;


我建议您访问plnkr.co,创建一个新的Angular 2(ES6)插件,并使其首先在其中工作。它将为您设置一切。一旦在那里工作,就将其复制到您的其他环境中,并对该环境的任何问题进行分类。

#9 楼

错误No provider for NameService是许多Angular2初学者面临的常见问题。

原因:在使用任何自定义服务之前,您首先必须通过将其添加到提供程序列表中,向NgModule注册它:

解决方案:

@NgModule({
    imports: [...],
    providers: [CustomServiceName]
})


#10 楼

您还可以在bootstrap命令中声明依赖项,例如:是链接:http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0

#11 楼

嗨,您可以在.ts文件中使用它:

首先在.ts文件中导入服务:

import { Your_Service_Name } from './path_To_Your_Service_Name';


然后在您可以添加相同的文件providers: [Your_Service_Name]

 @Component({
      selector: 'my-app',
      providers: [Your_Service_Name],
      template: `
        <h1>Hello World</h1> `   
    })


#12 楼

将其添加到提供者而非注射剂中

@Component({
    selector:'my-app',
    providers: [NameService]
})


#13 楼

在Angular中,您可以通过两种方式注册服务:

1。在模块或根组件中注册服务

效果:


在所有组件中可用
在生命周期应用程序中可用

如果将服务注册到延迟加载的模块中,则应注意以下事项:


该服务仅在声明为该模块的组件中可用
该服务将在生命周期应用程序上可用仅在加载模块时

2。将服务注册到任何其他应用程序组件中

效果:


将向该组件中注入服务的单独实例

如果将服务注册到任何其他应用程序组件中,则应当心


注入的服务的实例仅在该组件及其所有子组件中可用。
实例将在组件生命周期内可用。


#14 楼

您需要将其添加到providers数组中,其中包括组件上的所有依赖关系。

请参阅角度文档中的以下部分:


在组件中注册提供程序

这是一个经过修订的HeroesComponent,它在其
providers数组中注册了HeroService。


import { Component } from '@angular/core';

import { HeroService } from './hero.service';

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  <h2>Heroes</h2>
  <hero-list></hero-list>
  `
})
export class HeroesComponent { }



何时将NgModule与应用程序组件一起使用

一方面,NgModule中的提供程序已在root
注入器中注册。这意味着在NgModule中注册的每个提供程序
都可以在整个应用程序中访问。

另一方面,在应用程序组件中注册的提供程序
仅在该组件上可用。组件及其所有子组件。

这里,APP_CONFIG服务需要在整个
应用程序中都可用,因此它已在AppModule @NgModule提供程序
数组中注册。但是,由于HeroService仅在Heroes
功能区域中使用,而在其他地方没有使用,因此在
HeroesComponent中进行注册是有意义的。

另请参阅“我应该添加app-根AppModule或
根AppComponent的广泛提供者?”在NgModule常见问题解答中。


因此,在您的情况下,只需将注射剂更改为以下提供者:

@Component({
  selector: 'my-app',
  providers: [NameService]
})


Angular的新版本,@ View和其他一些东西不见了。

有关更多信息,请在此处访问。

#15 楼

将您的服务添加到app.module.ts文件中的provider []数组。
就像下面的

//在这里,我的服务是CarService

app.module.ts

import {CarsService} from './cars.service';

providers: [CarsService] // you can include as many services you have 


#16 楼

Angular2要求您在引导函数调用中声明所有可注入对象。没有此服务,您的服务就不是可注射的对象。

bootstrap(MyAppComponent,[NameService]);


评论


这不是很正确。我们可以在bootstrap()或组件的配置对象中的providers数组中包含服务。如果它包含在providers数组中,则每个绑定的组件将获得一个实例。有关更多信息,请参见“分层注射器”文档。

– Mark Rajcok
2015年11月14日在22:58



是的,正如@MarkRajcok所说,我们也仅在引导时提供在整个应用程序中必须使用的那些服务。通过这样做,我们不需要每次都在提供程序中进行注入,因为它将为每个组件创建实例。

–帕迪普·Ja那教
16年1月1日在5:05

#17 楼

将@Injectable添加为服务:

export class NameService {
    names: Array<string>;

    constructor() {
        this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
    }

    getNames() {
        return this.names;
    }
}


,并在组件中添加提供者为:

@Component({
    selector: 'my-app',
    providers: [NameService]
})


或者,如果您想在整个应用程序中访问服务,则可以传入应用程序提供商

#18 楼


Blockquote


在组件中注册提供程序

这里是经过修订的HeroesComponent,它在其provider数组中注册了HeroService。

import { Component } from '@angular/core';

import { HeroService } from './hero.service';

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  `
})
export class HeroesComponent { }