Angular2全球服务提供商

时间:2016-02-17 19:08:02

标签: angular angular2-services

/app
        - app.component.ts 
        - app.component.html (hide/show: menu bar)
        - app.global.service.ts (Public varible LoginSuccess:boolean)
        - main.ts
        /student
            - student.ts
            - student.service.ts
            - student.component.ts
            - student.component.html
        /security
            - login.component.ts (LoginSuccess = true)
            - login.component.html

在我的Angular2应用程序中,我有一个简单的需求,我想根据登录成功显示隐藏菜单栏。为此,我创建了一个只有LoginSuccess布尔变量的服务,我将在登录组件上设置该服务,并将在app.component.html上用于[hidden]=LoginSuccess导航标记。

我面临的问题是,即使注入app.global.service.ts constructor app.component.ts & login.component.ts的{​​{1}}值不存在,并且每个构造函数都创建了app.global.service.ts的新对象。

问题:如何通过服务在应用程序中保持单一值。在Angular2文档的某个地方,我确实读到了Injectable服务是单例。

6 个答案:

答案 0 :(得分:28)

你应该在bootstrap提供GlobalService,而不是每个组件:

bootstrap(AppComponent, [GlobalService])

@Component({
  providers: [], // yes
  // providers: [GlobalService], // NO.
})
class AppComponent {
  constructor(private gs: GlobalService) {
    // gs is instance of GlobalService created at bootstrap
  }
}

这种方式GlobalService将是单身人士。

有关更高级的方法,请参阅this answer

答案 1 :(得分:7)

您应该app.component.ts而不是在app.module.ts内部进行提升,而是将服务注入app.component.ts

...
import { MusicService } from './Services/music-service';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html',
    providers: [MusicService],
    ...
})
export class AppComponent {

constructor(private MS: MusicService) {

}
...

这是基于当前的Angular2版本。因此,在index.html内,您应该<app-root>加载AppComponent

现在要在任何其他组件中使用它,只需导入它:

import { MusicService } from './Services/music-service';

并初始化它:

constructor(private MS: MusicService) {

}

要点:

  1. 导入app.component.ts
  2. 作为app.component.ts
  3. 插入provider
  4. 在构造函数中初始化
  5. 对于希望在
  6. 中使用它的每个其他组件使用重复步骤2,3

    参考:Angular Dependency Injection

答案 2 :(得分:4)

作为Saxsa,关键是在应用程序注入器中定义服务提供者,而不是在每个组件级别定义。注意不要两次定义服务提供者......否则你仍然会有单独的服务实例。

这样您就可以共享同一个服务实例。

由于Angular2的分层注入器,会发生此行为。有关详细信息,您可以查看以下问题:

答案 3 :(得分:4)

截至最终版本(Angular 2.0.0):

导入服务并将其注入provider数组中,如下所示:

import { GlobalService } from './app.global.service';

//further down:
@NgModule({
  bootstrap: [ App ],
  declarations: [
    // Your components should go here 
  ],
  imports: [ 
    // Your module imports should go here
  ],
  providers: [ 
    ENV_PROVIDERS // By Angular
    // Your providers should go here, i.e.
    GlobalService
  ]
});

答案 4 :(得分:0)

我只想补充一下,因为我在这一点上陷入困​​境,虽然我使用的是Singelton,但您还必须使用Angular路由策略:

你不能使用href =“../ my-route”

因为这会启动整个应用程序的新功能:

而你必须使用:routerLink =“../ my-route”

答案 5 :(得分:0)

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

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

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