Twi*_*her 7 typescript angular-universal angular
我有一个像这样实施的守卫:
@Injectable()
export class CustomerGuard implements CanActivate {
constructor(
private authService: AuthenticationService,
private dialog: MatDialog
) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isCustomer) {
return true;
}
const dialog = this.dialog.open(SigninModalComponent, {
data: {
errorMessage: this.authService.isLoggedIn ?
'You don\t have access to this page, please use an appropriate account' :
'Please authenticate to access this page'
}
});
return dialog.afterClosed().pipe(
map(() => {
return this.authService.isCustomer;
})
);
}
}
Run Code Online (Sandbox Code Playgroud)
当我在浏览器的地址栏中键入未经授权的路由时,服务器端呈现显示惰性模式,然后当客户端接管时,会显示另一个工作模式,我可以成功验证并访问所请求的路由.
问题是服务器端渲染的模态永远不会消失......
是否有一个干净的解决方案,这并不意味着不显示服务器端的模式?
我会使用 DI 来帮助你解决这个问题。我利用他们网站上的Angular Universal示例来创建一个示例。
首先创建一个令牌:
app/tokens.ts
import { InjectionToken } from '@angular/core';
export let RENDERED_BY_TOKEN = new InjectionToken('renderedBy');
Run Code Online (Sandbox Code Playgroud)
更新app.module.ts
以使用此令牌通过 DI 容器提供值:
import { RENDERED_BY_TOKEN } from './tokens';
@NgModule({
.
.
.
providers: [
.,
.,
{ provide: RENDERED_BY_TOKEN, useValue: 'client' }
],
.
.
.
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
更新app.server.module.ts
以使用此令牌通过 DI 容器提供值:
import { RENDERED_BY_TOKEN } from './tokens';
@NgModule({
.
.
.
providers: [
.,
.,
{ provide: RENDERED_BY_TOKEN, useValue: 'server' }
],
.
.
.
export class AppServerModule { }
Run Code Online (Sandbox Code Playgroud)
然后在代码的其他地方(我使用了一个组件,但您可以将其放入路由保护中),利用该令牌注入值:
app.component.ts
import { Component, Inject } from '@angular/core';
import { RENDERED_BY_TOKEN } from './tokens';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
renderedBy;
constructor(@Inject(RENDERED_BY_TOKEN) val: string) {
this.renderedBy = val;
}
}
Run Code Online (Sandbox Code Playgroud)
app.component.html
<h1>{{title}}</h1>
<h5>{{renderedBy}}</h5>
<nav>
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
<app-messages></app-messages>
Run Code Online (Sandbox Code Playgroud)
如果运行此命令,您将看到h5
元素从“服务器”更新为“客户端”,表明其正常工作。您可以在 if 语句中的防护中使用此值,以便不在服务器渲染上显示该对话框。
更新
在阅读这篇文章时,我注意到一种更简单的方法。看起来 Angular 本身就可以为您提供这些信息,而无需自定义令牌。
在 Guard 中,您可以使用以下内容更新它:
import { PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
constructor(@Inject(PLATFORM_ID) private platformId: Object) {
const isServer = !isPlatformBrowser(platformId);
}
Run Code Online (Sandbox Code Playgroud)
更新2
鉴于对问题的澄清,我能够实现这一目标的唯一方法似乎有点不太理想,但这是迄今为止我发现的唯一可行的方法。
document.querySelectorAll('.cdk-overlay-container').forEach(dialog => dialog.remove());
Run Code Online (Sandbox Code Playgroud)
作为参考,我对此答案的所有工作都在GitHub 存储库中。
归档时间: |
|
查看次数: |
294 次 |
最近记录: |