我有一个登录表单http://localhost:4200/sign-in
,假设我填写了表单,然后决定进入http://localhost:4200/
主页。在我的AppRouting.ts
中,我有一个AuthGuard,可防止已通过 not 身份验证的用户进入首页并被重定向到“登录”页面。重定向回该表单后,它仍然像以前一样填写。因此,Angular以某种方式计算出我们将返回同一页面,因此没有理由刷新页面吗?因为如果我转到其他页面并返回登录表单,则会清除 。
我可以覆盖此行为吗?
我还尝试通过resetForm()
方法中的@ViewChild(NgForm) userSignInForm: NgForm;
通过ngOnInit
制作export const appRoutes: Routes = [
{ path: '', component: MainComponent, data: { title: 'main' }, canActivate: [AuthGuardService] }
];
,但是没有运气-我认为因为从未调用此方法,因为没有发生实际的组件重新加载。想法?
AppRouting:
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(
private authService: AuthService,
private router: Router,
private activatedRoute: ActivatedRoute
) { }
canActivate(): Observable<boolean> {
console.log('authGuard fired');
return this.authService.isUserAuthenticated().pipe(
map((isUserAuthenticated: boolean) => {
if (!isUserAuthenticated) {
this.router.navigate(['/sign-in'], {relativeTo: this.activatedRoute});
}
return isUserAuthenticated;
})
);
}
}
AuthGuardService:
<div class="container">
<form (ngSubmit)="onSubmit(userSignInForm)" #userSignInForm="ngForm" class="userSignInContainer">
<mat-card>
<mat-card-title>Sign-in</mat-card-title>
<mat-form-field>
<input matInput placeholder="email" type="email" [email]="true" [(ngModel)]="loginData.Email" name="Email" required>
</mat-form-field>
<mat-form-field>
<input matInput type="password" placeholder="password" [(ngModel)]="loginData.Password" name="Password" required>
</mat-form-field>
<mat-error *ngIf="!loginOrPassValid">{{errorMessage}}</mat-error>
<mat-card-actions>
<button mat-raised-button color="primary" type="submit" [disabled]="!userSignInForm.valid">sign-in</button>
</mat-card-actions>
</mat-card>
</form>
</div>
HTML(表单):
{{1}}
答案 0 :(得分:2)
您刚刚发现了Angular的行为:如果仍然需要更改URL,则不会破坏和重新创建组件。
例如,假设您有一个组件PersonalInfoComponent
,该组件根据url中指定的ID显示用户的个人信息。如果您看到ID为 14 的用户访问/user/14
的信息,然后转到/user/15
,则由于性能原因该组件将不会被破坏和重新创建,因此必须使用ActivatedRoute
可观察到的网址来检查网址是否更改。
这里发生的事情非常相似。首先,让我解释一下服务器端路由与客户端路由之间的区别,以便更清楚地说明实现此技巧的原因。
在服务器端路由中,页面的内容由于HTTP请求而发生更改。浏览器不知道该页面的内容,也无法对其进行任何预测。
在客户端路由中,视图由于单击而发生更改,并且在显示新内容后更新了URL。没有涉及服务器的请求,并且由于Angular确切知道目的地是什么,因此也可以避免在不需要时刷新和更新地址栏。例如,如果您从/
导航到/first-page
,并且/first-page
包含重定向到/second-page
的代码,则框架可以决定跳过中间步骤,只走从/
到/second-page
。
这就是正在发生的事情。您从/sing-in
转到/
,后者重定向到/sign-in
。因此,您从没有离开过页面。
如何覆盖此行为?您可以强制链接在服务器端代替客户端。
只需使用<a href="/">..</a>
代替<a routerLink="/">..</a>
答案 1 :(得分:1)
好的。 @CristianTraìna解释了为什么表格从未刷新过。就我而言,我不想使用<a href="/">..</a>
来强制重新加载,而只是使用Subject
来触发formReload
。
解决方案:
AuthService:
在AuthService中,我添加了
public resetSignInFormOnRedirect = new Subject();
然后进入
AuthGuardService:
canActivate(){
...
this.router.navigate(['/sign-in'], {relativeTo: this.activatedRoute});
this.authService.resetSignInFormOnRedirect.next();
...
}
登录组件:
ngOnInit() {
this.authService.resetSignInFormOnRedirect.subscribe(
() => {
this.userSignInForm.resetForm();
}
);
}