Angular2 全球服务商

Angular2 global service provider

/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.tsconstructorapp.component.ts & login.component.ts 值之后,也不会持续存在,并且每个构造函数都会创建 app.global.service.ts 的新对象。

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

您应该在 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就是单例了。

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

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

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

出现此行为是因为 Angular2 的分层注入器。更多细节,你可以看看这个问题:

  • What's the best way to inject one service into another in angular 2 (Beta)?

截至最终版本 (Angular 2.0.0):

导入服务并将其注入提供程序数组,如下所示:

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

您应该有一个 app.component.ts,而不是在 app.module.ts 内部进行 boostrapping,而是将服务注入 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. 作为 provider
  3. 插入 app.component.ts
  4. 在构造函数中初始化
  5. 对希望在
  6. 中使用的每个其他组件重复步骤 2,3

参考:Angular Dependency Injection

我只是补充一下,因为我被困在这一点上,虽然我使用了 Singelton,但你也必须使用 Angular 路由策略:

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

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

相反,您必须使用:routerLink="../my-route"