如何在没有路由的情况下使用 can-deactivate

时间:2021-07-08 10:35:23

标签: javascript node.js angular mean-stack

我的问题是我有一个父组件和一个子组件。父组件有表单,子组件有表单。所有子组件都共享父组件的同一路由,子组件没有任何路由器链接来唯一标识。所以任务是在表单脏并且用户导航离开该页面时显示弹出窗口。所以我实现了可以停用防护。所以在“app.module.ts”中,我如何为子组件提供can-deactivate(因为子组件没有任何路由器路径)。我怎样才能做到这一点? 检测未保存的更改并显示弹出窗口的任何替代方法?请帮助我

1 个答案:

答案 0 :(得分:0)

不过,它最初是为处理路由而设计的。

据我所知,父表单和子表单是完全独立的。因此,您可以在没有任何 URL 的情况下定义子组件并在那里放置一个守卫。请参阅下面的实现。

parent.component.ts

@Component({
  selector: 'parent-component',
  template: `
    <form>
      <input type="text" />
      <input type="text" />
    </form>

    //
    <!-- Here will be your child component -->
    <router-outlet></router-outlet>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
class ParentComponent {
  //... your parent form config
  public form: FormGroup = new FormGroup({});

  canDiscardChanges() {
    const { valid, pristine } = this.form;

    return valid || pristine;
  }
}

child.component.ts

@Component({
  selector: 'child-component',
  template: `
    <form>
      <input type="text" />
      <input type="text" />
    </form>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
class ChildComponentWithForms {
  //... your child form config
  public form: FormGroup = new FormGroup({});

  canDiscardChanges() {
    const { valid, pristine } = this.form;

    return valid || pristine;
  }
}

app-routing.module.ts

@NgModule({
  imports: [
    RouterModule.forChild([
      {
        path: 'parent-route',
        component: ParentComponent,
        canDeactivate: [DiscardChangesGuard],
        children: [
          {
            path: '',
            component: ChildComponentWithForms,
            canDeactivate: [DiscardChangesGuard]
          }
        ]
      }
    ])
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

discard-changes.guard.ts

import { Observable, of } from 'rxjs';

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

@Injectable({ providedIn: 'any' })
export class DiscardChangesGuard implements CanDeactivate<IDiscardChanges> {
  canDeactivate(component: IDiscardChanges) {
    if (component.canDiscardChanges instanceof Function) {
      return component.canDiscardChanges();
    }

    return of(true);
  }
}

export interface IDiscardChanges {
  canDiscardChanges(): Observable<boolean> | Promise<boolean> | boolean;
}
相关问题