Jas*_*aat 131 typescript angular2-routing angular2-services angular
我已经读过,当引导应该让所有孩子共享相同的实例时注入,但我的主要和头部组件(主应用程序包括头部件和路由器出口)都获得了我的服务的单独实例.
我有一个FacebookService,用于调用facebook javascript api和一个使用FacebookService的UserService.这是我的引导程序:
bootstrap(MainAppComponent, [ROUTER_PROVIDERS, UserService, FacebookService]);
Run Code Online (Sandbox Code Playgroud)
从我的日志记录看起来,引导调用结束,然后我看到FacebookService然后在每个构造函数运行的代码,MainAppComponent,HeaderComponent和DefaultComponent之前创建UserService:
Jas*_*aat 132
创建单例服务的推荐方法已更改.现在建议@Injectable在服务的装饰器中指定它应该在'root'中提供.这对我来说很有意义,并且不再需要在模块中列出所有提供的服务.您只需在需要时导入服务,并在适当的位置注册.您还可以指定模块,以便仅在导入模块时提供该模块.
@Injectable({
providedIn: 'root',
})
export class ApiService {
}
Run Code Online (Sandbox Code Playgroud)
使用NgModule,我现在的方法是创建一个包含服务类的"CoreModule",并在模块的提供者中列出服务.然后在主应用程序模块中导入核心模块,该模块将为在其构造函数中请求该类的任何子项提供一个实例:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ApiService } from './api.service';
@NgModule({
imports: [
CommonModule
],
exports: [ // components that we want to make available
],
declarations: [ // components for use in THIS module
],
providers: [ // singleton services
ApiService,
]
})
export class CoreModule { }
Run Code Online (Sandbox Code Playgroud)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
@NgModule({
declarations: [ AppComponent ],
imports: [
CommonModule,
CoreModule // will provide ApiService
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
如果列出了提供程序bootstrap(),则无需在组件装饰器中列出它们:
import { ApiService } from '../core/api-service';
@Component({
selector: 'main-app',
templateUrl: '/views/main-app.html',
// DO NOT LIST PROVIDERS HERE IF THEY ARE IN bootstrap()!
// (unless you want a new instance)
//providers: [ApiService]
})
export class MainAppComponent {
constructor(private api: ApiService) {}
}
Run Code Online (Sandbox Code Playgroud)
事实上,在'providers'中列出你的类会创建一个新的实例,如果任何父组件已经列出了它,那么孩子们不需要,如果他们这样做,他们将获得一个新的实例.
Thi*_*ier 125
杰森是完全正确的!它是由依赖注入的工作方式引起的.它基于分层注入器.
Angular2应用程序中有几个注入器:
当Angular2尝试在组件构造函数中注入某些内容时:
因此,如果您希望为整个应用程序提供单例,则需要在根注入器级别或应用程序组件注入器上定义提供程序.
但Angular2将从底部查看注入器树.这意味着将使用最低级别的提供程序,并且关联实例的范围将是此级别.
有关详细信息,请参阅此问题:
Joe*_*ida 24
我知道棱镜有分层注射器,如蒂埃里所说.
但是我在这里有另一种选择,以防你发现一个用例,你真的不想在父母那里注入它.
我们可以通过创建服务实例来实现这一点,并且提供始终返回的服务.
import { provide, Injectable } from '@angular/core';
import { Http } from '@angular/core'; //Dummy example of dependencies
@Injectable()
export class YourService {
private static instance: YourService = null;
// Return the instance of the service
public static getInstance(http: Http): YourService {
if (YourService.instance === null) {
YourService.instance = new YourService(http);
}
return YourService.instance;
}
constructor(private http: Http) {}
}
export const YOUR_SERVICE_PROVIDER = [
provide(YourService, {
deps: [Http],
useFactory: (http: Http): YourService => {
return YourService.getInstance(http);
}
})
];
Run Code Online (Sandbox Code Playgroud)
然后在您的组件上使用自定义提供方法.
@Component({
providers: [YOUR_SERVICE_PROVIDER]
})
Run Code Online (Sandbox Code Playgroud)
你应该有一个单独的服务,而不依赖于分层注入器.
我不是说这是一种更好的方法,以防万一有人出现无法使用分层注射器的问题.
Man*_*ain 16
语法已更改.检查此链接
依赖关系是注入器范围内的单例.在下面的示例中,HeroesComponent及其HeroListComponent子项之间共享一个HeroService实例.
步骤1.使用@Injectable装饰器创建单例类
@Injectable()
export class HeroService {
getHeroes() { return HEROES; }
}
Run Code Online (Sandbox Code Playgroud)
第2步.在构造函数中注入
export class HeroListComponent {
constructor(heroService: HeroService) {
this.heroes = heroService.getHeroes();
}
Run Code Online (Sandbox Code Playgroud)
步骤3.注册提供商
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
HttpModule,
JsonpModule
],
declarations: [
AppComponent,
HeroesComponent,
routedComponents
],
providers: [
HeroService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
小智 6
这似乎对我有用
@Injectable()
export class MyStaticService {
static instance: MyStaticService;
constructor() {
return MyStaticService.instance = MyStaticService.instance || this;
}
}
Run Code Online (Sandbox Code Playgroud)
这是Angular 2.3版的一个工作示例.只需像这个构造函数一样调用服务的构造函数(private _userService:UserService).它将为应用程序创建一个单例.
user.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Subject } from 'rxjs/Subject';
import { User } from '../object/user';
@Injectable()
export class UserService {
private userChangedSource;
public observableEvents;
loggedUser:User;
constructor() {
this.userChangedSource = new Subject<any>();
this.observableEvents = this.userChangedSource.asObservable();
}
userLoggedIn(user:User) {
this.loggedUser = user;
this.userChangedSource.next(user);
}
...
}
Run Code Online (Sandbox Code Playgroud)
app.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { UserService } from '../service/user.service';
import { User } from '../object/user';
@Component({
selector: 'myApp',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
loggedUser:User;
constructor(private _userService:UserService) {
this._userService.observableEvents.subscribe(user => {
this.loggedUser = user;
console.log("event triggered");
});
}
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
119576 次 |
| 最近记录: |