Angular CanDeactivate Guard递归触发,无法导航到组件
要求:当从当前组件(ProductsComponent)导航到其他组件(UsersComponent)时,向用户显示确认模式。如果用户希望离开,我必须导航到其他组件(SalesComponent),而不是UsersComponent 要实现上述目标,我将返回ProductsComponent中的canDeactivate()主题。当用户确认在subject中保留am发出UrlTree(salesComponent路径),但其触发canDeactivate递归并多次显示该模式时 知道怎么修吗?或者通过使用CanDeactivate guard,我如何导航到用户预期之外的其他组件 应用程序路由.module.tsAngular CanDeactivate Guard递归触发,无法导航到组件,angular,angular-ui-router,angular-router-guards,Angular,Angular Ui Router,Angular Router Guards,要求:当从当前组件(ProductsComponent)导航到其他组件(UsersComponent)时,向用户显示确认模式。如果用户希望离开,我必须导航到其他组件(SalesComponent),而不是UsersComponent 要实现上述目标,我将返回ProductsComponent中的canDeactivate()主题。当用户确认在subject中保留am发出UrlTree(salesComponent路径),但其触发canDeactivate递归并多次显示该模式时 知道怎么修吗?或者
const routes:Routes = [
{path: 'users', component: UsersComponent},
{path: 'products', component: ProductsComponent, canDeactivate:[CanExitGuard]},
{path: 'sales', component: SalesComponent}
];
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;
}
}
可以退出.guard.ts
const routes:Routes = [
{path: 'users', component: UsersComponent},
{path: 'products', component: ProductsComponent, canDeactivate:[CanExitGuard]},
{path: 'sales', component: SalesComponent}
];
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;
}
}
从'@angular/core'导入{Injectable};
从'@angular/router'导入{CanDeactivate,ActivatedRouteSnapshot,RouterStateSnashot,UrlTree};
从“rxjs”导入{Observable};
导出接口CanComponentDeactivate{
canDeactivate:()=>布尔| UrlTree |可观察|承诺;
}
@可注射({providedIn:'root'})
导出类CanExitGuard实现CanDeactivate{
canDeactivate(组件:CanComponentDeactivate,
currentRoute:ActivatedRouteSnapshot,
currentState:RouterStateSnapshot,
nextState?:路由器状态快照):布尔值| UrlTree |可观察|承诺{
返回component.canDeactivate?component.canDeactivate():true;
}
}
products.component.ts,请注意,我使用了超时和确认对话框来模拟异步操作
import { Component, OnInit } from '@angular/core';
import { CanComponentDeactivate } from '../can-exit.guard';
import { Router,RouterStateSnapshot, 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$;
}
}
从'@angular/core'导入{Component,OnInit};
从“../can exit.guard”导入{CanComponentDeactivate};
从'@angular/Router'导入{Router,routerstatesnashot,UrlTree};
从'rxjs'导入{Subject};
@组成部分({
选择器:'应用程序产品',
templateUrl:“./products.component.html”,
样式URL:['./products.component.css']
})
导出类产品组件实现OnInit,CanComponentDeactivate{
导航选择$:主题=新主题();
构造函数(专用路由器:路由器){}
恩戈尼尼特(){
}
canDeactivate(){
log('Can Deactivate triggered…');
const isconfirm:boolean=confirm(“您想离开产品吗?确定-转到销售页面”);
//模拟异步
设置超时(()=>{
如果(未确认){
log(“导航到销售页面”);
const UrlTree:UrlTree=this.router.createUrlTree(['sales']);
this.navigationSelection$.next(UrlTree);
}否则{
console.log(“导航已取消”);
this.navigationSelection$.next(false);
}
}, 7000);
返回此。navigationSelection$;
}
}
您可以通过添加额外的检查来解决此问题:
canDeactivate(
组件:CanComponentDeactivate,
currentRoute:ActivatedRouteSnapshot,
currentState:RouterStateSnapshot,
下一个状态?:路由器状态快照
):布尔值| UrlTree |可观察|承诺{
返回component.canDeactivate&&nextState.url=='/users'?component.canDeactivate():true;
}
您希望确保仅在从/products
导航到/users
时显示模式
.您可以通过添加额外的检查来解决此问题:
canDeactivate(
组件:CanComponentDeactivate,
currentRoute:ActivatedRouteSnapshot,
currentState:RouterStateSnapshot,
下一个状态?:路由器状态快照
):布尔值| UrlTree |可观察|承诺{
返回component.canDeactivate&&nextState.url=='/users'?component.canDeactivate():true;
}
您希望确保仅在从/products
导航到/users
时显示模式
.谢谢@Andrei,首先,这不是实际的项目,我只是创建了这个示例来复制我的场景。因此,在我的实际项目中,用户可以离开“/产品”路线进行许多其他操作。所以我不能像你说的那样开支票。此外,我还在其他路由中重复使用相同的保护。@Uzma您可以在“data”属性中添加要检查和访问的URL,在guardHanks@Andrei中,首先这不是实际的项目,我创建这个示例只是为了复制我的场景。因此,在我的实际项目中,用户可以离开“/产品”路线进行许多其他操作。所以我不能像你说的那样开支票。此外,我还在其他路由中重复使用相同的保护。@Uzma您可以在“数据”属性中添加要检查和访问的URL