我的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;与任何元素都不匹配
任何帮助表示感谢。
答案 0 :(得分:21)
我最终还是搞清楚了。这可以比我的实现更简单,但我希望将引导保留在main.ts
中,而不是将其粘贴在请求重新启动的服务中。
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());
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();
}