2017-04-05 93 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