admin管理员组文章数量:1406951
I am trying to add CanDeactivate
functionality in my ponent.I have a
form in which there is one input
field and button. i want if user enter something in input field and move to next screen
without submit it will show a dialog box .if user enter yes
from the dialog bix then it go to next ponent else it remain in same screen .
here is my code ponent.ts
import {CanDeactivate} from '@angular/router';
import { HelloComponent } from './helloponent';
export default class DeactivateGuard implements CanDeactivate<HelloComponent> {
canDeactivate(ponent: HelloComponent): boolean {
if (!ponent.canDeactivate()) {
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
}
return true;
}
}
currently when I am typing something on input
field and click next
button it give me error
ERROR
Error: Uncaught (in promise): TypeError: Cannot read property 'ngInjectableDef' of undefined
TypeError: Cannot read property 'ngInjectableDef' of undefined
at resolveNgModuleDep (/@angular/[email protected]/bundles/core.umd.js:9309:31)
at NgModuleRef_.get (/@angular/[email protected]/bundles/core.umd.js:10003:16)
at PreActivation.getToken (/@angular/[email protected]/bundles/router.umd.js:3014:25)
at MergeMapSubscriber.eval [as project] (
I am trying to add CanDeactivate
functionality in my ponent.I have a
form in which there is one input
field and button. i want if user enter something in input field and move to next screen
without submit it will show a dialog box .if user enter yes
from the dialog bix then it go to next ponent else it remain in same screen .
here is my code https://stackblitz./edit/angular-ctwnid?file=src%2Fapp%2Fhello.ponent.ts
import {CanDeactivate} from '@angular/router';
import { HelloComponent } from './hello.ponent';
export default class DeactivateGuard implements CanDeactivate<HelloComponent> {
canDeactivate(ponent: HelloComponent): boolean {
if (!ponent.canDeactivate()) {
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
}
return true;
}
}
currently when I am typing something on input
field and click next
button it give me error
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/[email protected]/bundles/core.umd.js:9309:31)
at NgModuleRef_.get (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/[email protected]/bundles/core.umd.js:10003:16)
at PreActivation.getToken (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/[email protected]/bundles/router.umd.js:3014:25)
at MergeMapSubscriber.eval [as project] (https://angular-ctwnid.stackblit
Share
edited Aug 27, 2018 at 18:09
James
22.4k5 gold badges29 silver badges43 bronze badges
asked Aug 27, 2018 at 17:30
user944513user944513
12.8k52 gold badges185 silver badges348 bronze badges
2 Answers
Reset to default 5I think an ideal implementation would be to create an interface that would allow the Guard to be reusable.
Here's how:
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(
ponent: CanComponentDeactivate,
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (!ponent.confirm()) {
return confirm('You have unsaved changes! If you leave, your changes will be lost.');
}
}
}
Then this CanComponentDeactivate
Interface should be implemented the ponent on which you have to place this guard. That's how it would be forced to implement the confirm
method from where the returned boolean value is what you'd want to check in the canDeactivate
method of your guard.
Something along the lines of this:
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;
}
}
One final thing would be to also add the Guard as a provider. After all, it's a service. So add it to the providers
array:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/mon/http';
import { RouterModule, Routes } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.ponent';
import { HelloComponent } from './hello.ponent';
import { ErrorComponent } from './error.ponent';
import { DeactivateGuard } from './deactivate.gaurd';
import { TestService } from './test.service';
import { TestResolver } from './test.resolver';
import { HTTP_INTERCEPTORS } from '@angular/mon/http';
import { NextComponent } from './next/next.ponent';
const routes: Routes = [{
path: 'home',
ponent: HelloComponent,
canDeactivate: [DeactivateGuard]
},
{
path: 'next',
ponent: 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 {}
This should make the guard work for you. Here's your Updated StackBlitz
you have not passed the deactivae guard in providers on app.module.ts , edited your stackbiltz
providers: [TestService,TestResolver,DeactivateGuard
]
本文标签: javascripthow to add CanDeactivate functionality in componentStack Overflow
版权声明:本文标题:javascript - how to add CanDeactivate functionality in component? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744917993a2632114.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论