Javascript 什么';在angular 2(Beta版)中,将一个服务注入另一个服务的最佳方式是什么?
我知道如何将服务注入组件(通过@component),但如何使用DI在组件之外传递服务 换句话说,我不想这样做:Javascript 什么';在angular 2(Beta版)中,将一个服务注入另一个服务的最佳方式是什么?,javascript,angular,Javascript,Angular,我知道如何将服务注入组件(通过@component),但如何使用DI在组件之外传递服务 换句话说,我不想这样做: export class MyFirstSvc { } export class MySecondSvc { constructor() { this.helpfulService = new MyFirstSvc(); } } export class MyThirdSvc { constructor() { this.
export class MyFirstSvc {
}
export class MySecondSvc {
constructor() {
this.helpfulService = new MyFirstSvc();
}
}
export class MyThirdSvc {
constructor() {
this.helpfulService = new MyFirstSvc();
}
}
- 将您的服务“提供”到您打算使用它们的位置或更高的位置,例如,如果您只需要每个服务的一个实例(单实例),您可以使用
将它们放在应用程序的根目录下bootstrap()
- 在依赖于其他服务的任何服务上使用
装饰器@Injectable()
- 将其他服务注入依赖服务的构造函数中
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
import {MyFirstSvc} from '../services/MyFirstSvc';
import {MySecondSvc} from '../services/MySecondSvc';
bootstrap(AppComponent, [MyFirstSvc, MySecondSvc]);
MySecondSvc.ts
import {Injectable} from 'angular2/core';
import {MyFirstSvc} from '../services/MyFirstSvc';
@Injectable()
export class MySecondSvc {
constructor(private _firstSvc:MyFirstSvc) {}
getValue() {
return this._firstSvc.value;
}
}
有关其他文件,请参见
服务DI有点奇怪的是,它仍然依赖于组件。例如,
MySecondSvc
是在组件请求时创建的,这取决于组件树中“提供”了MyFirstSvc
的位置,这可能会影响将哪个MyFirstSvc
实例注入MySecondSvc
。此处将对此进行详细讨论:服务被认为是在组件之间共享的。假设我有一个服务,我可以在不同的组件中使用它
在这个回答中,我向您展示了一个服务,它接受来自一个组件的数据,并将数据发送到另一个组件
我使用了路由、共享服务、共享对象的概念。
我希望这将有助于您了解共享服务的基本原理
注意:@Injectable装饰器用于使服务可注入
Boot.ts
import {Component,bind} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {Router,ROUTER_PROVIDERS,RouteConfig, ROUTER_DIRECTIVES,APP_BASE_HREF,LocationStrategy,RouteParams,ROUTER_BINDINGS} from 'angular2/router';
import {SharedService} from 'src/sharedService';
import {ComponentFirst} from 'src/cone';
import {ComponentTwo} from 'src/ctwo';
@Component({
selector: 'my-app',
directives: [ROUTER_DIRECTIVES],
template: `
<h1>
Home
</h1>
<router-outlet></router-outlet>
`,
})
@RouteConfig([
{path:'/component-first', name: 'ComponentFirst', component: ComponentFirst}
{path:'/component-two', name: 'ComponentTwo', component: ComponentTwo}
])
export class AppComponent implements OnInit {
constructor(router:Router)
{
this.router=router;
}
ngOnInit() {
console.log('ngOnInit');
this.router.navigate(['/ComponentFirst']);
}
}
bootstrap(AppComponent, [SharedService,
ROUTER_PROVIDERS,bind(APP_BASE_HREF).toValue(location.pathname)
]);
是的,第一件事是在要注入的每个服务上添加
@Injectable
装饰器。事实上,可注入的
名称有点阴险。这并不意味着该类将是“可注入的”,但它将进行修饰,以便可以注入构造函数参数。有关更多详细信息,请参阅此github问题:
以下是我对注入机制的理解。为类设置@Injectable
装饰器时,Angular将尝试为当前执行链的注入器中的相应类型创建或获取实例。事实上,对于Angular2应用程序,不仅有一个喷油器,还有一个喷油器树。它们与整个应用程序和组件隐式关联。这一级别的一个关键特性是,它们以分层方式链接在一起。此喷油器树映射了部件树。没有为“服务”定义喷油器
我们来取样吧。本人有以下申请:
- Component
:在AppComponent
函数中创建Angular2应用程序时提供的我的应用程序的主要组件bootstrap
@Component({ selector: 'my-app', template: ` <child></child> `, (...) directives: [ ChildComponent ] }) export class AppComponent { }
- 两个服务,
和Service1
:Service2
由Service1
子组件使用,
由Service2
Service1
@Injectable() export class Service1 { constructor(service2:Service2) { this.service2 = service2; } getData() { return this.service2.getData(); } }
Application
|
AppComponent
|
ChildComponent
getData() --- Service1 --- Service2
在这种应用中,我们有三个喷油器:
- 可使用
引导功能的第二个参数配置的应用程序注入器
- 可使用此组件的
属性配置的providers
喷油器。它可以“查看”应用程序中定义的元素。这意味着,如果在此提供程序中找不到提供程序,将自动在此父注入器中查找该提供程序。如果未在后者中找到,将抛出“未找到提供程序”错误AppComponent
喷油器将遵循与ChildComponent
喷油器相同的规则。要注入为组件执行的注入链中涉及的元素,将首先在此注入器中查找提供者,然后在AppComponent
中查找提供者,最后在应用程序中查找提供者AppComponent
Service1
注入ChildComponent
构造函数时,Angular2将查看ChildComponent
注入器,然后查看AppComponent
注入器,最后查看应用程序注入器
由于需要将Service2
注入Service1
,因此将执行相同的解析处理:ChildComponent
注入器、AppComponent
一个和应用程序一个
这意味着可以使用组件的providers
属性和应用程序的bootstrap
功能的第二个参数,根据需要在每个级别指定Service1
和Service2
这允许共享一组元素的依赖项实例:
- 如果在应用程序级别定义提供程序,则创建的相应代码实例将由整个应用程序(所有组件、所有服务等)共享
- 如果在组件级别定义提供者,则该实例将由组件本身、其子组件以及依赖关系链中涉及的所有“服务”共享
Thierry在Angular2.0.0-beta.17中,当连接组件A->ServiceB->ServiceC时,不知何故@Injectable不适合我 我采取了这种做法:
@Component({selector: 'my-app',
template: `Hello! This is my app <br/><br/><overview></overview>`,
directives: [OverviewComponent]
})
class AppComponent {}
bootstrap(AppComponent);
概述-service.ts
import {PropertiesService} from "./properties-service";
import {Inject} from 'angular2/core';
export class OverviewService {
private propertiesService:PropertiesService;
// Using @Inject in constructor
constructor(@Inject(PropertiesService) propertiesService:PropertiesService){
this.propertiesService = propertiesService;
}
logHello(){
console.log("hello");
this.propertiesService.logHi();
}
}
// Using @Injectable here doesn't make a difference
export class PropertiesService {
logHi(){
console.log("hi");
}
}
属性-service.ts
import {PropertiesService} from "./properties-service";
import {Inject} from 'angular2/core';
export class OverviewService {
private propertiesService:PropertiesService;
// Using @Inject in constructor
constructor(@Inject(PropertiesService) propertiesService:PropertiesService){
this.propertiesService = propertiesService;
}
logHello(){
console.log("hello");
this.propertiesService.logHi();
}
}
// Using @Injectable here doesn't make a difference
export class PropertiesService {
logHi(){
console.log("hi");
}
}
首先要做的是注释所有的ser
@Component({selector: 'my-app',
template: `Hello! This is my app <br/><br/><overview></overview>`,
directives: [OverviewComponent]
})
class AppComponent {}
bootstrap(AppComponent);
import {Component, bind} from 'angular2/core';
import {OverviewService} from "../services/overview-service";
import {PropertiesService} from "../services/properties-service";
@Component({
selector: 'overview',
template: `Overview listing here!`,
providers:[OverviewService, PropertiesService] // Include BOTH services!
})
export default class OverviewComponent {
private propertiesService : OverviewService;
constructor( overviewService: OverviewService) {
this.propertiesService = overviewService;
overviewService.logHello();
}
}
import {PropertiesService} from "./properties-service";
import {Inject} from 'angular2/core';
export class OverviewService {
private propertiesService:PropertiesService;
// Using @Inject in constructor
constructor(@Inject(PropertiesService) propertiesService:PropertiesService){
this.propertiesService = propertiesService;
}
logHello(){
console.log("hello");
this.propertiesService.logHi();
}
}
// Using @Injectable here doesn't make a difference
export class PropertiesService {
logHi(){
console.log("hi");
}
}
@Injectable()
export class MyFirstSvc {
}
@Injectable()
export class MySecondSvc {
constructor(helpfulService: MyFirstSvc) {
}
}
@Injectable()
export class MyThirdSvc {
constructor(helpfulService: MyFirstSvc) {
}
}
import { Component } from "@angular/core"
import { DataService } from "./data.service"
@Component({
selector:"test-component",
template:`<ul>
<li *ngFor="let person of persons">{{ person.name }}</li>
</ul>
})
export class TestComponent {
persons:<Array>;
constructor(private _dataService:DataService){
this.persons = this._dataService.getPersons()
}
}
export class DataService {
persons:<Array>;
constructor(){
this.persons = [
{name: "Apoorv"},
{name: "Bryce"},
{name: "Steve"}
]
}
getPersons(){
return this.persons
}
import { Http } from '@angular/http';
export class DataService {
persons:<Array>;
constructor(){
this.persons = [
{name: "Apoorv"},
{name: "Bryce"},
{name: "Steve"}
]
}
getPersons(){
return this.persons
}
bootstrap(AppComponent,[MyFirstSvc]);
@Component({
...
providers:[MyFirstSvc]
}
...
export class MySecondSvc {
constructor(private myFirstSvc : MyFirstSvc ){}
}