gpt4 book ai didi

javascript - 如何在组件中添加 CanDeactivate 功能?

转载 作者:行者123 更新时间:2023-12-03 01:15:20 33 4
gpt4 key购买 nike

我正在尝试在我的组件中添加 CanDeactivate 功能。我有一个其中有一个输入字段和按钮的表单。我希望如果用户在输入字段中输入某些内容并移动到下一个屏幕而不提交,它将显示一个对话框。如果用户从对话框中输入"is",那么它会转到下一个组件,否则它保留在同一屏幕中。

这是我的代码 https://stackblitz.com/edit/angular-ctwnid?file=src%2Fapp%2Fhello.component.ts

import {CanDeactivate} from '@angular/router';
import { HelloComponent } from './hello.component';

export default class DeactivateGuard implements CanDeactivate<HelloComponent> {

canDeactivate(component: HelloComponent): boolean {

if (!component.canDeactivate()) {
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
}
return true;
}

}

目前,当我在输入字段中输入内容并单击下一步按钮时,会出现错误

ERROR
Error: Uncaught (in promise): TypeError: Cannot read property 'ngInjectableDef' of undefined
TypeError: Cannot read property 'ngInjectableDef' of undefined
at resolveNgModuleDep (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/core@6.0.0/bundles/core.umd.js:9309:31)
at NgModuleRef_.get (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/core@6.0.0/bundles/core.umd.js:10003:16)
at PreActivation.getToken (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/router@6.0.0/bundles/router.umd.js:3014:25)
at MergeMapSubscriber.eval [as project] (https://angular-ctwnid.stackblit

最佳答案

我认为理想的实现是创建一个允许 Guard 可重用的接口(interface)。

方法如下:

import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

export interface CanComponentDeactivate {
confirm(): boolean;
}

@Injectable()
export class DeactivateGuard implements CanDeactivate < CanComponentDeactivate > {
canDeactivate(
component: CanComponentDeactivate,
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (!component.confirm()) {
return confirm('You have unsaved changes! If you leave, your changes will be lost.');
}
}
}

那么这个 CanComponentDeactivate 接口(interface)应该由您必须在其上放置此防护的组件实现。这就是强制实现 confirm 方法的方式,其中返回的 bool 值就是您想要在守卫的 canDeactivate 方法中检查的值。

类似的事情:

import { Component, Input } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CanComponentDeactivate } from './deactivate.guard';

@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>
<form novalidate [formGroup]="sfrm" class="calform">
<input type="text" formControlName="name"/>
<button type="submit">submit</button>
</form>
<a [routerLink]="['/next']">next</a>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent implements CanComponentDeactivate {
@Input() name: string;
sfrm: FormGroup

constructor(private fb: FormBuilder) {
this.sfrm = this.fb.group({
name: ['']
});
}

confirm() {
return this.sfrm.submitted || !this.sfrm.dirty;
}

}

最后一件事是将 Guard 添加为提供者。毕竟,这是一项服务。因此,将其添加到 providers 数组中:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule, Routes } from '@angular/router';

import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { ErrorComponent } from './error.component';
import { DeactivateGuard } from './deactivate.gaurd';

import { TestService } from './test.service';
import { TestResolver } from './test.resolver';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NextComponent } from './next/next.component';
const routes: Routes = [{
path: 'home',
component: HelloComponent,
canDeactivate: [DeactivateGuard]
},
{
path: 'next',
component: NextComponent
},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
}
];
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot(routes),
HttpClientModule,
FormsModule
],
declarations: [
AppComponent,
HelloComponent,
ErrorComponent,
NextComponent
],
bootstrap: [AppComponent],
providers: [
TestService,
TestResolver,
DeactivateGuard
]
})
export class AppModule {}

这应该会让守卫为你工作。这是你的Updated StackBlitz

关于javascript - 如何在组件中添加 CanDeactivate 功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52044306/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com