英文:
Angular register provider at component level
问题
当你在组件级别注册提供者时,你会在每个该组件的新实例中获得一个新的服务实例。在这个术语中,服务是给定组件对象的一个实例变量,这意味着该服务是它的依赖项。该依赖项可以通过构造函数注入到组件中。
// 相对于下面的工作示例
constructor(private service: HeroService) { }
并由Angular框架管理。在这个上下文中,构造函数注入的行为可以被理解为(伪代码):
class Component {
private Service service;
constructor(Service service) {
this.service = service;
}
}
这意味着如果创建了一个组件对象,在我们的案例中是HeroList
类的一个实例,那么我们将我们的依赖项(HeroService
实例)注入(传递)到HeroList
构造函数中 (HeroList hl = new HeroList(new HeroService())
)。
为什么第2点下的代码没有满足第1点中工作示例的表示/解释?
hero.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class HeroService {
constructor() { }
}
hero-list.component.ts
import { Component } from '@angular/core';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
styleUrls: ['./hero-list.component.css'],
providers: [ HeroService ]
})
export class HeroListComponent {
constructor(private service: HeroService) { }
}
hero.service.ts
export class HeroService {
constructor() { }
}
hero-list.component.ts
import { Component } from '@angular/core';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
styleUrls: ['./hero-list.component.css'],
})
export class HeroListComponent {
constructor(private service: HeroService) { }
}
如果我将HeroListComponent
类修改为:
export class HeroListComponent {
private service: HeroService;
constructor() {
this.service = new HeroService();
}
}
那么你也会在每个该组件的新实例中获得一个新的服务实例。这样,我们也满足了组合模式(两个对象之间的“拥有关系”)的要求。
英文:
When you register a provider at the component level, you get a new instance of the service with each new instance of that component. In this term, the service is a instance variable of a given component object that means the service is his dependency. The dependency can be injected into component by constructor injection
//with respect to the working example below
constructor( private service: HeroService ) { }
and is managed by Angular framework. In this context the line of constructor injection can be read as (pseudo code):
class Component {
private Service service;
constructor( Service service) {
this.service = service;
}
}
That means if a component object is created, in our case an instance of class HeroList, then we inject(pass) our dependency(HeroService instance) to HeroList constructor (HeroList hl = new HeroList(new HeroService())
).
Why code under point 2. does not fulfilled the representation/interpretation of the working example in point 1?
1)
hero.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class HeroService {
constructor() { }
}
hero-list.component.ts
import { Component } from '@angular/core';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
styleUrls: ['./hero-list.component.css'],
providers: [ HeroService ]
})
export class HeroListComponent {
constructor( private service: HeroService ) { }
}
2)
hero.service.ts
export class HeroService {
constructor() { }
}
hero-list.component.ts
import { Component } from '@angular/core';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
styleUrls: ['./hero-list.component.css'],
})
export class HeroListComponent {
constructor( private service: HeroService ) { }
}
If I modify HeroListComponent class to:
export class HeroListComponent {
private service: HeroService;
constructor( ) {
this.service = new HeroService();
}
}
then you get also new instance of the service with each new instance of that component. And we fulfilled the composite pattern ("has-a" relationship between two objects) as well.
答案1
得分: 1
第一个方法是有效的方法,而第二个方法则不是。
第一个方法
正如你所解释的那样。你正在为组件范围提供服务(创建一个新实例)。这意味着这个服务实例可以在你的组件及其所有子组件中用作依赖项。
第二个方法
如果这是有意使用 TypeScript 类作为服务而没有使用 @Injectable
装饰器,那么它将无法正常工作。要使其正常工作,你需要在需要它的地方提供该类,例如在你的组件范围内,使用 类提供程序对象 在 providers 数组中如下所示:
providers: [{ provide: HeroService, useClass: HeroService }]
在 Angular 应用程序中,注入器对象 负责创建你的服务的单例实例,并将其作为依赖项提供给你组件的构造函数。此对象需要知道你的服务在哪个范围内可用(提供)才能正确地完成其工作。如果没有这些信息,你将收到编译错误。
英文:
The difference
The first approach is a working approach and the second one is not.
The first approach
As you've explained exactly. You are providing a service (creating a new instance) on the component scope. Wich means this service instance could be used as a dependency in your component and all it's children.
The second approach
If this was on on purpose to use a typescript class as a service without the @Injectable
decorator, it will not work this way. To make it work you need to provide the class where it's needed e.g. on your component scope with the help of the class provider object under the providers array like:
providers: [ {provide: HeroService, useClass: HeroService]
In angular application the injector object is responsible for creating a singletone instance of your service and provide it as a dependency in the constructor of your component. This object needs to know on which scope your service is avaliable (provided) to be able to do its job properly. Without this information you will get a compilation error.
答案2
得分: 1
当你在一个类上使用Injectable
注解时,你告诉Angular将该类注册为一个service
,并可以通过应用程序的依赖注入
(DI)提供该类。
另一个类只是一个普通的JavaScript类。当你尝试通过DI来使用它时,你将会得到一个众所周知的错误:
NullInjectorError: No provider for HeroService!
因此,第一个方法是一个有效的服务,而另一个则不是。
英文:
When you have a class with the Injectable
annotation, you are telling Angular to have that class registered as a service
and can be provided through the application via dependency injection
(DI).
The other one, is just a plain javascript class. When you try to use it via DI, you'll get well known error:
NullInjectorError: No provider for HeroService!
Look at console output in this demo
So the first approach is a valid service, the other one isn't.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论