重置Angular 2应用程序

时间:2017-04-05 14:40:37

标签: angular angular2-services

我的Angular 2应用程序具有注销功能。如果可以的话,我们希望避免执行页面重新加载(即document.location.href = '/';),但是注销过程需要重置应用程序,以便当其他用户登录时,前一个会话中没有剩余数据。

这是我们的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()方法。我们的user-authentication.service中的logout方法启动destroy:

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

这会出现以下错误:

  

选择器&#34; app-root&#34;与任何元素都不匹配

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:21)

我最终还是搞清楚了。这可以比我的实现更简单,但我希望将引导保留在main.ts中,而不是将其粘贴在请求重新启动的服务中。

  1. 创建一个单例,为Angular和非Angular(main.ts)提供通信方式:
  2. 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);
      }
    }
    
    1. 调整main.ts以订阅重启请求:
    2. 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());
      
      1. 将NgZone添加到触发注销的服务:
      2. 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的要求是避免错误:

          

        预计不会进入Angular Zone,但确实如此!

答案 1 :(得分:4)

我遇到了同样的问题。一种更简单的方法是使用location.reload()

当用户单击注销按钮时,App.component中的函数应如下所示。

logout() {
  //Auth Logout service call
  this.auth.logout();
  //Router Navigation to Login Page
  this.router.navigate(['login']);
  //Reload Angular to refresh components and prevent old data from loading up for a 
  //another user after login. This especially applies lazy loading cases. 
  location.reload(); 
}