15
/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并没有持续存在并且每个构造函数都创建app.global.service.ts.

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

4

5 回答 5

29

您应该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将是一个单例。

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

于 2016-02-17T19:15:43.733 回答
7

你应该有一个app.component.tsand 而不是在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.tsprovider
  3. 在构造函数中初始化
  4. 重复步骤 2,3 为所有其他组件使用希望使用它

参考:Angular 依赖注入

于 2016-10-23T03:13:32.783 回答
4

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

这样,您将能够共享相同的服务实例。

这种行为是由于 Angular2 的分层注入器而发生的。有关更多详细信息,您可以查看此问题:

于 2016-02-17T20:04:59.300 回答
4

截至最终版本(Angular 2.0.0):

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

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
  ]
});
于 2016-09-15T10:31:46.993 回答
0

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

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

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

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

于 2017-10-26T12:46:38.553 回答