首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在组件中添加CanDeactivate功能?

如何在组件中添加CanDeactivate功能?
EN

Stack Overflow用户
提问于 2018-08-27 17:30:43
回答 2查看 3.8K关注 0票数 1

我尝试在我的组件中添加CanDeactivate功能,我有一个表单,其中有one input字段和按钮。我希望如果用户在输入字段中输入一些内容,然后在没有提交的情况下移动到下一个screen,它将显示一个对话框,.if用户从对话框bix中输入yes,然后转到下一个组件,否则它将保持在相同的屏幕中。

这是我的代码https://stackblitz.com/edit/angular-ctwnid?file=src%2Fapp%2Fhello.component.ts

代码语言:javascript
复制
import {CanDeactivate} from '@angular/router';
import { HelloComponent } from './hello.component';

export default class DeactivateGuard implements CanDeactivate<HelloComponent> {

  canDeactivate(component: HelloComponent): boolean {

    if (!component.canDeactivate()) {
      if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
        return true;
      } else {
        return false;
      }
    }
    return true;
  }

}

当前,当我在input字段上键入某些内容并单击next按钮时,它会给我带来错误

代码语言:javascript
复制
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/core@6.0.0/bundles/core.umd.js:9309:31)
at NgModuleRef_.get (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/core@6.0.0/bundles/core.umd.js:10003:16)
at PreActivation.getToken (https://angular-ctwnid.stackblitz.io/turbo_modules/@angular/router@6.0.0/bundles/router.umd.js:3014:25)
at MergeMapSubscriber.eval [as project] (https://angular-ctwnid.stackblit
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-27 17:49:33

我认为理想的实现应该是创建一个界面,从而使卫队可以被重用。

下面是操作步骤:

代码语言:javascript
复制
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方法的地方。

与此类似的东西:

代码语言:javascript
复制
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数组中:

代码语言:javascript
复制
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

票数 3
EN

Stack Overflow用户

发布于 2018-08-27 17:49:37

您还没有通过在app.module.ts上的提供者中的停用保护,编辑了您的stackbiltz

代码语言:javascript
复制
     providers: [TestService,TestResolver,DeactivateGuard  
  ]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52044306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档