简体   繁体   English

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

In my application of Angular2, I have a simple need where I want to show hide menu bar based on login success. 在我的Angular2应用程序中,我有一个简单的需求,我想根据登录成功显示隐藏菜单栏。 For that I created a service which just have a LoginSuccess boolean varilable, which I would set on login component and will use on app.component.html for [hidden]=LoginSuccess nav tag. 为此,我创建了一个只有LoginSuccess布尔变量的服务,我将在登录组件上设置,并将在app.component.html上使用[hidden]=LoginSuccess nav标签。

Problem I am facing is, even after injecting app.global.service.ts thru constructor of app.component.ts & login.component.ts value is not persisting and each constructor creating new object of app.global.service.ts . 我面临的问题是,即使在通过app.component.ts & login.component.ts constructor注入app.global.service.ts之后,值也不会持久存在,并且每个构造函数都会创建app.global.service.ts新对象。

Question: How can I achieve to persist single value across application thru service. 问题:如何通过服务在应用程序中保持单个值。 Somewhere in Angular2 docs, I did read that Injectable service is singleton. 在Angular2文档的某个地方,我确实读到了Injectable服务是单例。

You should provide GlobalService at bootstrap, and not for each component: 您应该在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
  }
}

This way GlobalService will be a singleton. 这样GlobalService一个单例。

For more advanced approach see this answer . 有关更高级的方法,请参阅此答案

You should have an app.component.ts and instead of boostrapping inside of app.module.ts you inject the service into app.component.ts . 您应该有一个app.component.ts而不是在app.module.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) {

}
...

This is based off the current Angular2 build. 这是基于当前的Angular2构建。 So inside index.html you should have <app-root> where AppComponent is loaded. 所以在index.html里面你应该有<app-root>加载AppComponent地方。

Now to use it inside any other component use just import it: 现在要在任何其他组件中使用它只需导入它:

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

and initialize it: 并初始化它:

constructor(private MS: MusicService) {

}

Summary: 摘要:

  1. Import into app.component.ts 导入app.component.ts
  2. Insert into app.component.ts as a provider 作为provider插入app.component.ts
  3. Initialize in constructor 在构造函数中初始化
  4. Repeat step 2,3 for every other component use wish to use it in 对于希望使用它的每个其他组件使用重复步骤2,3

Reference: Angular Dependency Injection 参考: 角度依赖注入

As Saxsa, the key point is to define your service provider within the application injector and not at each component level. 作为Saxsa,关键是在应用程序注入器中定义服务提供者,而不是在每个组件级别定义。 Be careful not to define the service provider twice... Otherwise you will still have separate service instances. 注意不要两次定义服务提供者......否则,您仍将拥有单独的服务实例。

This way you will be able to share the same instance of the service. 这样您就可以共享同一个服务实例。

This behavior occurs because of hierarchical injectors of Angular2. 出现此问题的原因是Angular2的分层注入器。 For more details, you could have a look at this question: 有关更多详细信息,您可以查看以下问题:

As of final release (Angular 2.0.0) : 截至最终版本(Angular 2.0.0):

Import the service and inject it in the providers array like so : 导入服务并将其注入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
  ]
});

Beginning with Angular 6.0 , the preferred way to create a singleton services is to specify on the service that it should be provided in the application root. Angular 6.0开始,创建单例服务的首选方法是在服务上指定应在应用程序根目录中提供它。 This is done by setting providedIn to root on the service's @Injectable decorator: 这是通过在服务的@Injectable装饰器@Injectable providedInroot来完成的:

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

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

I will just add, because i was stuck at this point to, although i used a Singelton, you also have to use the Angular routing strategie: 我只想补充一下,因为我在这一点上被困住了,虽然我使用的是Singelton,但你还必须使用Angular路由策略:

You can't use href="../my-route" 你不能使用href =“../ my-route”

cause this starts the whole application new: 因为这启动整个应用程序新:

instead you have to use: routerLink="../my-route" 相反,你必须使用:routerLink =“../ my-route”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM