2017-04-05 96 views
0

我的Angular 2應用程序具有註銷功能。如果可以的話,我們希望避免重新加載頁面(即document.location.href = '/';),但註銷過程需要重置應用程序,以便在其他用戶登錄時沒有來自上一個會話的殘留數據。重置Angular 2應用程序

這裏是我們的main.ts文件:

import 'es6-shim/es6-shim'; 
import './polyfills';  
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
import { ComponentRef, enableProdMode } from '@angular/core'; 
import { environment } from '@environment'; 
import { AppModule } from './app/app.module'; 

if (environment.production === true) { 
    enableProdMode(); 
} 

const init =() => { 
    platformBrowserDynamic().bootstrapModule(AppModule) 
    .then(() => (<any>window).appBootstrap && (<any>window).appBootstrap()) 
    .catch(err => console.error(err)); 
}; 

init(); 

platformBrowserDynamic().onDestroy(() => { 
    init(); 
}); 

你可以看到,我試圖調用init()方法時,該應用程序被破壞。在我們的用戶authentication.service啓動註銷方法破壞:

logout() { 
    this.destroyAuthToken(); 
    this.setLoggedIn(false); 
    this.navigateToLogin() 
    .then(() => { 
    platformBrowserDynamic().destroy(); 
    }); 
} 

這提供了以下錯誤:

The selector "app-root" did not match any elements

任何幫助表示讚賞。

+0

我想當你打電話給platformBrowserDynamic()時,你會得到一個新的平臺。您可能需要在第一次調用它時存儲引用,然後在該函數上調用destroy()。 – mcgraphix

回答

3

最後我終於明白了這一點。這可能比我的實現更簡單,但我想保留在main.ts中的引導,而不是將其保存在請求重啓的服務中。

  1. 創建用於角和非角(main.ts)提供了一種單例進行通信:

boot-control.ts

import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 
export class BootController { 
    private static instance: BootController; 
    private _reboot: Subject<boolean> = new Subject(); 
    private reboot$ = this._reboot.asObservable(); 

    static getbootControl() { 
    if (!BootController.instance) { 
     BootController.instance = new BootController(); 
    } 
    return BootController.instance; 
    } 

    public watchReboot() { 
    return this.reboot$; 
    } 

    public restart() { 
    this._reboot.next(true); 
    } 
} 
  • 調整main.ts訂閱重新啓動請求:
  • main.ts

    import { enableProdMode, NgModuleRef, NgModule } from '@angular/core'; 
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
    import { AppModule } from './app/app.module'; 
    import { environment } from './environments/environment'; 
    import { BootController } from './boot-control'; 
    
    if (environment.production) { 
        enableProdMode(); 
    } 
    
    const init =() => { 
        platformBrowserDynamic().bootstrapModule(AppModule) 
        .then(() => (<any>window).appBootstrap && (<any>window).appBootstrap()) 
        .catch(err => console.error('NG Bootstrap Error =>', err)); 
    } 
    
    // Init on first load 
    init(); 
    
    // Init on reboot request 
    const boot = BootController.getbootControl().watchReboot().subscribe(() => init()); 
    
  • 添加NgZone到觸發註銷服務:
  • user-auth.service.ts

    import { BootController } from '@app/../boot-control'; 
    import { Injectable, NgZone } from '@angular/core'; 
    
    @Injectable() 
    export class UserAuthenticationService { 
        constructor (
         private ngZone: NgZone, 
         private router: Router 
        ) {...} 
    
        logout() { 
         // Removes auth token kept in local storage (not strictly relevant to this demo) 
         this.removeAuthToken(); 
    
         // Triggers the reboot in main.ts   
         this.ngZone.runOutsideAngular(() => BootController.getbootControl().restart()); 
    
         // Navigate back to login 
         this.router.navigate(['login']); 
        } 
    } 
    

    的NgZone要求是避免錯誤:

    Expected to not be in Angular Zone, but it is!

    +1

    你只是讓我的一天:)真棒解決方案。 – iJungleBoy