问题描述
要求:从当前组件(ProductsComponent)导航到不同组件(UsersComponent)时向用户显示确认模式。如果用户希望离开,则必须导航到其他组件(SalesComponent)而不是UsersComponent。 / p>
为实现上述目的,我在ProductsComponent中的canDeactivate()中返回了Subject。当用户确认在主题中保留发射UrlTree(salesComponent路径)但其触发可以递归停用并最终多次显示模式时。
任何想法如何解决?或通过使用CanDeactivate Guard,如何导航到用户预期之外的其他组件?
app-routing.module.ts
const routes:Routes = [
{path: 'users',component: UsersComponent},{path: 'products',component: ProductsComponent,canDeactivate:[CanExitGuard]},{path: 'sales',component: SalesComponent}
];
can-exit.guard.ts
import { Injectable } from '@angular/core';
import { CanDeactivate,ActivatedRouteSnapshot,RouterStateSnapshot,UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree>;
}
@Injectable({ providedIn: 'root' })
export class CanExitGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate,currentRoute: ActivatedRouteSnapshot,currentState: RouterStateSnapshot,nextState?: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
products.component.ts ,请注意,我使用了“超时并确认”对话框来模拟异步操作。
import { Component,OnInit } from '@angular/core';
import { CanComponentDeactivate } from '../can-exit.guard';
import { Router,UrlTree } from '@angular/router';
import { Subject } from 'rxjs';
@Component({
selector: 'app-products',templateUrl: './products.component.html',styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit,CanComponentDeactivate {
navigationSelection$: Subject<boolean | UrlTree> = new Subject();
constructor(private router: Router) { }
ngOnInit() {
}
canDeactivate() {
console.log('Can Deactivate triggered...');
const isConfirmed: boolean = confirm("Do you want to leave products? Ok - Takes to sales page");
//simulate asynchronous
setTimeout(()=>{
if(isConfirmed){
console.log('navigates to sales page');
const UrlTree: UrlTree = this.router.createUrlTree(['sales']);
this.navigationSelection$.next(UrlTree);
} else {
console.log('navigation Canceled');
this.navigationSelection$.next(false);
}
},7000);
return this.navigationSelection$;
}
}
解决方法
您可以通过添加其他检查来解决此问题:
canDeactivate(
component: CanComponentDeactivate,currentRoute: ActivatedRouteSnapshot,currentState: RouterStateSnapshot,nextState?: RouterStateSnapshot
): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
return component.canDeactivate && nextState.url === '/users' ? component.canDeactivate() : true;
}
您要确保仅当从/products
导航到/users
时才显示模式。