ChatGPT解决这个技术问题 Extra ChatGPT

Angular 没有 NameService 的提供者

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

应用程序.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);

服务/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({ providers: [NameService] })

K
Klas Mellbourn

您必须使用 providers 而不是 injectables

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

Complete code sample here


面向未来 google 员工的更新:使用 providers 可在最新的测试版(测试版 0)上运行。
@nathanhleung 绑定和提供程序都有效 - 这是暂时的还是他们只是在内部做同样的事情
@Simon_Weaver 嗯,他们可能在最新的 beta 版本中对其进行了更改 - 在 beta.0 中我无法让它与 bindings 一起使用
@nathanhleung 似乎供应商也进入了发行版。
如果该服务是从另一个服务中使用的怎么办?我将它添加到模块提供程序中,我认为这可以使其在全球范围内可用,但仍然出现该错误
M
Mark Rajcok

在 Angular 2 中,您可以在三个地方“提供”服务:

引导根组件 其他组件或指令

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

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

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

Plunker

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

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

有关详细信息,请参阅 Hierarchical Injectors 文档。


这是一个非常好的答案。它进一步解释了在根组件中声明服务与在其他子组件中声明服务之间的区别。
m
magiccrafter

从 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]
})

P
Pankaj Parkar

您应该在 AppModuleNgModule 元数据的 providers 数组中注入 NameService

@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 您是否在正确的模块中注入您的服务? DataManagerService 上面有 @Injectable 装饰器吗?
D
Derrick Miller

令人震惊的是,最新版本的 Angular 中的语法又发生了变化 :-) 从 Angular 6 docs

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

src/app/user.service.0.ts

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

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

s
saghar.fadaei

您应该在 AppModule 的 NgModule 元数据的 providers 数组中注入 NameService。

@NgModule({
   providers: [MyService]
})

并确保以相同的名称(区分大小写)导入您的组件,因为 SystemJs 区分大小写(按设计)。如果您在项目文件中使用不同的路径名,如下所示:

主模块.ts

import { MyService } from './MyService';

你的组件.ts

import { MyService } from './Myservice';

然后 System js 将进行双重导入


出色的!在使用桶对导入进行分组时,我遇到了这个错误。您的 SystemJS 提示帮助了我 :)
s
supercobra

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

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


u
unobf

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) plunk 并首先让它在那里工作。它会为你准备好一切。一旦它在那里工作,将其复制到您的其他环境并对该环境的任何问题进行分类。


t
trixn

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

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

解决方案:

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

T
Tobias Gassmann

您还可以在 bootstrap-command 中声明依赖项,例如:

bootstrap(MyAppComponent,[NameService]);

至少那是在 alpha40 中对我有用的。

这是链接:http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0


S
Shubham Verma

嗨,您可以在 .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> `   
    })

G
Gopinath Kaliappan

将其添加到提供程序而不是注射剂

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

R
Rzv Razvan

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

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

效果:

适用于所有组件

终生申请可用

如果您将服务注册到延迟加载的模块中,您应该小心:

该服务仅适用于在该模块中声明的组件

只有在加载模块时,该服务才能在生命周期应用程序中可用

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

效果:

将一个单独的Service实例注入到组件中

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

注入服务的实例将仅可用于组件及其所有子组件。

该实例将在组件生命周期内可用。


A
Alireza

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

在 Angular 文档中查看此部分:

在组件中注册提供者 这是一个修改后的 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 中的提供程序在根注入器中注册。这意味着在 NgModule 中注册的每个提供程序都可以在整个应用程序中访问。另一方面,在应用程序组件中注册的提供程序仅在该组件及其所有子组件上可用。在这里,APP_CONFIG 服务需要在整个应用程序中都可用,因此它在 AppModule @NgModule 提供程序数组中注册。但是由于 HeroService 只在 Heroes 功能区域中使用,而在其他地方没有使用,因此在 HeroesComponent 中注册它是有意义的。另请参阅“我应该将应用程序范围的提供程序添加到根 AppModule 还是根 AppComponent?”在 NgModule 常见问题解答中。

因此,在您的情况下,只需将可注射剂更改为提供程序,如下所示:

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

同样在新版本的 Angular 中,@View 和其他一些东西都消失了。

有关详细信息,请访问 here


T
The Hungry Dictator

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

// 这里我的服务是 CarService

app.module.ts

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

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

C
Chanaka Weerasinghe

块引用

在组件中注册提供程序

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

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

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

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

M
Mark Rajcok

Angular2 要求你在 bootstrap 函数调用中声明所有的可注入对象。没有这个,你的服务就不是一个可注入的对象。

bootstrap(MyAppComponent,[NameService]);

这并不完全正确。我们可以将服务包含在 bootstrap() 或组件配置对象的 providers 数组中。如果它包含在 providers 数组中,我们会为每个绑定组件获取一个实例。有关详细信息,请参阅 Hierarchical Injectors 文档。
是的,正如@MarkRajcok 所说,我们也只在引导时提供那些我们必须在整个应用程序中使用的服务。通过这样做,我们不需要每次都在提供程序中注入,因为它会为每个组件创建实例。
R
Rob

将@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]
})

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