2016-02-17 124 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 

在我的Angular2應用程序中,我基於登錄成功需要顯示隱藏菜單欄。爲此,我創建了一個只有LoginSuccess布爾變量的服務,我將在登錄組件上設置該服務,並將在app.component.html上使用[hidden]=LoginSuccess nav標記。我對着Angular2全球服務提供商

問題是,即使注入app.global.service.tsapp.component.ts & login.component.ts價值constructor不是持久的,並且每個構造函數創建的app.global.service.ts新對象後。

問題:如何才能實現跨應用程序通過服務保持單個值。在Angular2文檔中的某處,我讀了Injectable服務是單例。

回答

23

你應該在引導提供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將是一個單例。

更高級的方法請參閱this answer

+0

什麼樣,如果我們想在引導的時候提供一些組件,如我們在Globalservice中做過? –

+1

只是說:如果注入singleton(全局)服務的組件位於單獨的文件中,那麼您仍然必須在該文件中使用import語句來加載服務:從「./」導入{AuthService}。 services/auth.service「;' – Samuel

+7

但是,如果我不把它添加到提供者:[]我得到一個錯誤; 例外:沒有GlobalService的提供者! –

4

作爲Saxsa,關鍵在於在應用程序注入器中定義服務提供者,而不是在每個組件級別定義服務提供者。小心不要兩次定義服務提供者......否則,你仍然會有不同的服務實例。

這樣你就可以共享相同的服務實例。

此行爲是由於Angular2的分層注入器發生的。有關詳細信息,你可以看一下這個問題:

4

至於最終版本(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 
    ] 
}); 
+0

http://stackoverflow.com/a/36159062/3779853說你不應該這樣做 – Blauhirn

+0

@Blauhim這與馬雷克斯的答案不同。 mareks代碼中的提供者是全球性的。你引用的答案是關於在每個組件中實例化一個提供者。 –

5

你應該有一個app.component.ts和替代boostrapping內的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.ts爲一個provider
  3. 初始化構造
  4. 每隔組件使用重複步驟2,3希望在使用它

參考:Angular Dependency Injection

0

我只是補充,因爲我被困在這點,雖然我使用了Singelton,但您也必須使用Angular路由策略:

您不能使用href =「../ my-route」

原因這將啓動整個應用新:

相反,你必須使用:routerLink =「../我的路線」