Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 有没有办法让角路由器保护CanDeactivate在表单组件中充当保护/接口?_Angular_Angular Router_Angular Router Guards - Fatal编程技术网

Angular 有没有办法让角路由器保护CanDeactivate在表单组件中充当保护/接口?

Angular 有没有办法让角路由器保护CanDeactivate在表单组件中充当保护/接口?,angular,angular-router,angular-router-guards,Angular,Angular Router,Angular Router Guards,我读过关于使用CanDeactivate检测用户是否离开表单/路由的文章,这正是我在项目中需要的。我试着实现这个答案: 当我查看我的用户表单组件时,我将信息输入其中一个输入,然后尝试刷新,单击另一个组件,通过浏览器url导航到google.com。所有这些都不会触发该答案中的确认提示 我的项目结构设置如下: > src > app - app-routing.module.ts - app.module.ts - app.component.ts - app.com

我读过关于使用CanDeactivate检测用户是否离开表单/路由的文章,这正是我在项目中需要的。我试着实现这个答案:

当我查看我的用户表单组件时,我将信息输入其中一个输入,然后尝试刷新,单击另一个组件,通过浏览器url导航到google.com。所有这些都不会触发该答案中的确认提示

我的项目结构设置如下:

> src
 > app
  - app-routing.module.ts
  - app.module.ts
  - app.component.ts
  - app.component.html
  > auth
   > ...
  > dashboard
   - dashboard.module.ts
   - dashboard.component.ts
   - dashboard.component.html
   > components
    > forms
     - user-form.component.ts
     - user-form.component.html
    > ...
  > shared
   > guards
    - pending-changes.guard.ts
   > ...
我已经尝试过实现这个答案:

在我的仪表板模块中,我导入了pending-changes.guard,并为我的仪表板组件定义了一个路由,该组件使用我的canDeactivate:[PendingChangesGuard] 然后,我将PendingChangesGuard作为仪表板模块的NgModule中的提供者添加

在我的用户表单组件中,我从共享中的PendingChangesGuard导入ComponentCanDeactivate,然后在组件中实现ComponentCanDeactivate接口。我定义了一个名为canDeactivate()的函数,该函数检查FormGroup类型的userForm是否脏,如果脏,则返回false,这将向用户显示确认信息。如果表单没有被使用,那么我想返回true

“我的仪表板”模块中定义的路线是针对我的仪表板组件的。我的仪表板组件是我的用户表单组件的另一个组件的父级。因此,当用户通过单击其他组件来显示该组件时,包含表单html的“我的用户表单”组件没有专门设置自己的url/path/route/routerLink。我不确定这里的设置是否正确,因为我看到的大多数示例都专门为表单组件设置了一个route/path/routerLink,其中包含会触发用户提示的未保存数据

挂起的更改.guard.ts

import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean | Observable<boolean>;
}

@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
    // if there are no pending changes, just allow deactivation; else confirm first
    return component.canDeactivate() ?
      true :
      // NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
      // when navigating away from your angular app, the browser will show a generic warning message
      // see http://stackoverflow.com/a/42207299/7307355
      confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
  }
}
import { PendingChangesGuard } from '../shared/guards/pending-changes.guard';

export const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canDeactivate: [PendingChangesGuard]
  }
];

@NgModule({
  imports: [
    CodemirrorModule,
    CommonModule,
    CronEditorModule,
    FormsModule,
    ReactiveFormsModule,
    SimpleNotificationsModule.forRoot(),
    NgbModule,
    NgxsModule.forFeature(STATES),
    NgxSpinnerModule,
    RouterModule.forChild(routes),
    SharedModule
  ],
  declarations: COMPONENTS,
  exports: COMPONENTS,
  entryComponents: [ProfileComponent],
  providers: [PendingChangesGuard]
})
export class DashboardModule {}

import { ComponentCanDeactivate } from '../../../../shared/guards/pending-changes.guard';
@Component({
  selector: 'user-form',
  templateUrl: './user-form.component.html',
  styleUrls: ['./user-form.component.scss']
})
export class UserFormComponent implements OnInit, ComponentCanDeactivate {
  ...

  userForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  // @HostListener allows us to also guard against browser refresh, close, etc.
  @HostListener('window:beforeunload')
  canDeactivate(): Observable<boolean> | boolean {
    // insert logic to check if there are pending changes here;
    if (this.userForm.dirty === true) return false;
    return true;
    // returning true will navigate without confirmation
    // returning false will show a confirm dialog before navigating away
  }

  ...
}
const routes: Routes = [
  {
    path: 'dashboard',
    canActivate: [AuthGuard],
    loadChildren: './dashboard/dashboard.module#DashboardModule'
  },
  {
    path: '',
    redirectTo: '/dashboard',
    pathMatch: 'full'
  }
];
用户表单.component.ts

import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean | Observable<boolean>;
}

@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
    // if there are no pending changes, just allow deactivation; else confirm first
    return component.canDeactivate() ?
      true :
      // NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
      // when navigating away from your angular app, the browser will show a generic warning message
      // see http://stackoverflow.com/a/42207299/7307355
      confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
  }
}
import { PendingChangesGuard } from '../shared/guards/pending-changes.guard';

export const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canDeactivate: [PendingChangesGuard]
  }
];

@NgModule({
  imports: [
    CodemirrorModule,
    CommonModule,
    CronEditorModule,
    FormsModule,
    ReactiveFormsModule,
    SimpleNotificationsModule.forRoot(),
    NgbModule,
    NgxsModule.forFeature(STATES),
    NgxSpinnerModule,
    RouterModule.forChild(routes),
    SharedModule
  ],
  declarations: COMPONENTS,
  exports: COMPONENTS,
  entryComponents: [ProfileComponent],
  providers: [PendingChangesGuard]
})
export class DashboardModule {}

import { ComponentCanDeactivate } from '../../../../shared/guards/pending-changes.guard';
@Component({
  selector: 'user-form',
  templateUrl: './user-form.component.html',
  styleUrls: ['./user-form.component.scss']
})
export class UserFormComponent implements OnInit, ComponentCanDeactivate {
  ...

  userForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  // @HostListener allows us to also guard against browser refresh, close, etc.
  @HostListener('window:beforeunload')
  canDeactivate(): Observable<boolean> | boolean {
    // insert logic to check if there are pending changes here;
    if (this.userForm.dirty === true) return false;
    return true;
    // returning true will navigate without confirmation
    // returning false will show a confirm dialog before navigating away
  }

  ...
}
const routes: Routes = [
  {
    path: 'dashboard',
    canActivate: [AuthGuard],
    loadChildren: './dashboard/dashboard.module#DashboardModule'
  },
  {
    path: '',
    redirectTo: '/dashboard',
    pathMatch: 'full'
  }
];