Angular2 global service provider

2019-01-22 21:49发布

/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. 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.

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.

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.

6条回答
够拽才男人
2楼-- · 2019-01-22 22:07

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:

You can't use href="../my-route"

cause this starts the whole application new:

instead you have to use: routerLink="../my-route"

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-22 22:08

You should have an app.component.ts and instead of boostrapping inside of app.module.ts you inject the service into 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. So inside index.html you should have <app-root> where AppComponent is loaded.

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
  2. Insert into app.component.ts as a provider
  3. Initialize in constructor
  4. Repeat step 2,3 for every other component use wish to use it in

Reference: Angular Dependency Injection

查看更多
乱世女痞
4楼-- · 2019-01-22 22:11

You should provide GlobalService at bootstrap, and not for each component:

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.

For more advanced approach see this answer.

查看更多
闹够了就滚
5楼-- · 2019-01-22 22:15

As of final release (Angular 2.0.0) :

Import the service and inject it in the providers array like so :

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
  ]
});
查看更多
虎瘦雄心在
6楼-- · 2019-01-22 22:17

As Saxsa, the key point is to define your service provider within the application injector and not at each component level. 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. For more details, you could have a look at this question:

查看更多
forever°为你锁心
7楼-- · 2019-01-22 22:24

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. This is done by setting providedIn to root on the service's @Injectable decorator:

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

@Injectable({
  providedIn: 'root',
})
export class UserService {
}
查看更多
登录 后发表回答