Я реализовал canDeactivate
guard при добавлении, редактировании компонента, который отображает диалоговое окно в качестве компонента подтверждения. Guard работает и отображает диалоговое окно подтверждения, когда я нажимаю routerLink
. Проблема в том, что когда я пытаюсь перейти от TypeScript, я получаю
"Error: No component factory found for ConfirmationDialogComponent. Did you add it to @NgModule.entryComponents?".
Вот мои настройки маршрутизации. App-Routing
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthenticationGuardService], children: []
},
{
path: 'home',
component: EngagementComponent,
canActivate: [AuthenticationGuardService], children: [
{
path: 'engagement',
component: EngagementSurveyComponent,
canActivate: [AuthenticationGuardService],
canDeactivate: [CanDeactivateGuard]
},
{
path: 'edit-project/:projectId',
component: EditProjectComponent,
canActivate: [AuthenticationGuardService],
canDeactivate: [CanDeactivateGuard]
}
]
},
{
path: 'project-reports/:projectId',
component: ProjectReportsComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'project-report/:projectId',
component: GenerateReportComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'project-participants/:projectId',
component: ProjectParticipantsComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'project-status/:projectId',
component: EngagementStatusComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'project-responses/:participantId/:projectId',
component: EngagementResponsesComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'news',
component: NewsComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'questionaire/:uuid',
component: QuestionnaireComponent,
canActivate: [AuthenticationGuardService]
},
{
path: 'questionaire-thanks',
component: QuesCompleteThankComponent,
canActivate: [AuthenticationGuardService]
},
{ path: 'copy-project/:projectId', component: CopyProjectComponent, canActivate: [AuthenticationGuardService] },
{ path: 'report-project-list', component: ReportProjectListComponent, canActivate: [AuthenticationGuardService] }
];
Код компонента, куда я направляюсь к другому компоненту:
@Component({
selector: 'app-engagement-survey',
templateUrl: './engagement-survey.component.html',
styleUrls: ['./engagement-survey.component.scss']
})
export class EngagementSurveyComponent implements OnInit, OnDestroy {
constructor(public dialog: MatDialog, private projectService: ProjectListService,
private router: Router,
private fb: FormBuilder, private clientService: ClientService) {
this.projectForm = this.fb.group({
title: [''],
description: ['']
});
this.sampleSetup = this.fb.group({
template: [''],
categoryList: this.fb.array([])
});
this.questionSetup = this.fb.group({
template: [''],
questions: this.fb.array([])
});
this.participantForm = this.fb.group({
participants: this.fb.array([]),
});
}
ngOnInit() {
localStorage.removeItem('secondStep');
this.subscription = this.clientService.currentClient.subscribe(currentClientValue => {
if (this.isClientChanged) {
this.router.navigate(['/home']); **// PROBLEM HERE**
} else {
this.isClientChanged = true;
}
});
this.addCategorie(this.participants);
this.questionList = [];
this.projectService.loadSampleFrameTemplate().subscribe((resp) => {
this.templatesList = resp;
});
this.projectService.loadTemplateOptions(1).subscribe((resp) => {
this.papulateParticipants(resp);
});
// this.addQuestionCategorie();
this.getProjectEmailTemplate();
this.getDefaultQuestionSetTemplate();
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
canDeactivate(): Observable<boolean> {
if (!this.dataSaved) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
width: '350px',
data: 'Leave Site? Changes you made may not be saved? '
});
return dialogRef.afterClosed();
} else {
return of(true);
}
}
}
Может деактивировать реализацию защиты ниже:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable, of } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean>;
}
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate): Observable<boolean> {
return component.canDeactivate ? component.canDeactivate() : of(true);
}
}
Я добавил этот компонент диалога подтверждения в массиве entryCompnents в модуле приложения, а также в массиве объявлений. Это прекрасно работает, когда я ухожу от компонента, используя некоторую директиву routerLink
, но с this.router.navigate('/someroute')
Есть ли какая-то разница в обоих направлениях или в обходе этого?