2016-02-17 11 views
11
/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 

W mojej aplikacji Angular2, mam prostą potrzebę, gdy chcę pokazać pasek menu ukrywania oparty na sukcesie logowania. W tym celu utworzyłem usługę, która ma zmienną logikę LoginSuccess, którą ustawiłbym na komponencie logowania i użyję na app.component.html dla tagu nawigacji o numerze [hidden]=LoginSuccess.Globalny dostawca usług Angular2

Problem jestem stoi to, że nawet po wstrzyknięciu app.global.service.ts thru constructor od app.component.ts & login.component.ts wartość nie jest utrzymująca się i każdy konstruktor tworząc nowy obiekt app.global.service.ts.

Pytanie: Jak mogę osiągnąć pojedynczą wartość w całej aplikacji przez usługę. Gdzieś w dokumentach Angular2 przeczytałem, że usługa Injectable jest singleton.

Odpowiedz

23

Należy dostarczyć GlobalService w bootstrap, a nie dla każdego komponentu:

bootstrap(AppComponent, [GlobalService]) 

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

ten sposób GlobalService będzie pojedyncza.

Bardziej zaawansowane podejście można znaleźć pod numerem this answer.

+0

A co jeśli chcemy zapewnić pewne elementy w momencie bootstrap, jak zrobiliśmy w Globalservice? –

+1

Po prostu mówiąc: jeśli komponent, do którego wstrzykujesz usługę singleton (globalną), znajduje się w osobnym pliku, musisz jednak użyć instrukcji import w tym pliku, aby załadować usługę: 'import {AuthService} from" ./ services/auth.service ";' – Samuel

+7

Ale jeśli nie dodaję tego do dostawców: [] pojawia się błąd; WYJĄTEK: Brak operatora dla GlobalService! –

4

Kluczową sprawą Saxssa jest zdefiniowanie dostawcy usług w iniektorze aplikacji, a nie na każdym poziomie komponentu. Uważaj, aby dwukrotnie nie zdefiniować dostawcy usług ... W przeciwnym razie nadal będziesz mieć oddzielne instancje usług.

W ten sposób będzie można udostępnić to samo wystąpienie usługi.

To zachowanie występuje z powodu hierarchicznych wtryskiwaczy Angular2. Aby uzyskać więcej informacji, można spojrzeć na to pytanie:

4

Od ostatecznej wersji (2.0.0): kątowe

zaimportować serwis i wstrzyknąć go dostawców tablica tak:

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

http://stackoverflow.com/a/36159062/3779853 mówi, że nie powinieneś tego robić – Blauhirn

+0

@Blauhim Różni się od odpowiedzi mareks. Dostawcy w kodzie mareks są globalni. Odpowiedź, o której wspomniałeś, dotyczyła utworzenia dostawcy w każdym komponencie. –

5

należy mieć app.component.ts i zamiast boostrapping wewnątrz app.module.ts Wstrzykujesz usługę do 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) { 

} 
... 

ta opiera się aktualny Angular2 budować. Więc wewnątrz index.html powinieneś mieć <app-root> gdzie załadowany jest AppComponent.

Teraz go używać wewnątrz innego wykorzystania składnika tylko importować go:

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

i zainicjować go:

constructor(private MS: MusicService) { 

} 

Podsumowanie:

  1. importu do app.component.ts
  2. Insert w app.component.ts jako provider
  3. Initialize w konstruktorze
  4. Powtórz krok 2,3 dla każdego innego wykorzystania składnika chcą używać go w

referencyjny: Angular Dependency Injection

0

Dodam jeszcze, ponieważ utknąłem w tym punkt, chociaż użyłem Singelton, trzeba również używać kątowego Strategie routingu:

nie można używać href = „../ my-trasę”

przyczyna ta rozpoczyna całą aplikację nowego:

zamiast trzeba użyć: routerLink = „../ my-trasę”