Я думаю, что идеальной реализацией было бы создание интерфейса, который позволял бы многократно использовать Guard.
Вот как:
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
интерфейсе должен быть реализован компонент, на котором вы должны разместить эту защиту. Вот как будет принудительно реализован метод confirm
, откуда возвращаемое логическое значение - это то, что вы хотели бы проверить в методе 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;
}
}
И последнее - добавить Стража в качестве поставщика. В конце концов, это услуга. Так что добавьте его в массив 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 {}
Это должно заставить охранника работать на вас. Вот ваш Обновленный StackBlitz