Angular 角形验证成功后没有重定向

Angular 角形验证成功后没有重定向,angular,angular2-routing,angular-reactive-forms,Angular,Angular2 Routing,Angular Reactive Forms,今天,在成功验证angular Responsive form后,我遇到了angular routing的一个问题。我想要实现的就是验证表单中的密码字段,如果成功重定向到另一个组件(“/customers”),或者如果密码不相同,我们应该什么都不做,并给用户一个重新键入正确密码的机会 注册组件 @Component({ selector: 'app-registration', templateUrl: './registration.component.html', styleU

今天,在成功验证angular Responsive form后,我遇到了angular routing的一个问题。我想要实现的就是验证表单中的密码字段,如果成功重定向到另一个组件
(“/customers”)
,或者如果密码不相同,我们应该什么都不做,并给用户一个重新键入正确密码的机会

注册组件


@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;
  email$: Observable<string>;

  constructor(private formBuilder: FormBuilder, private customerService: CustomerService, private router: Router) {
  }

  ngOnInit() {

    this.registerForm = this.formBuilder.group({
      username: ['', Validators.required],
      email: ['', Validators.required],
      name: ['', Validators.required],
      surname: ['', Validators.required],
      phoneNumber: ['', Validators.required],
      nip: ['', Validators.required],
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required],
    }, {
      validator: MustMatch('password', 'confirmPassword')
    });
  }

  get form() {
    return this.registerForm.controls;
  }

  onSubmit() {
    this.submitted = true;

    const registeredCustomer: RegistrationForm = {

      username: this.registerForm.controls.username.value,
      email: this.registerForm.controls.email.value,
      name: this.registerForm.controls.name.value,
      surname: this.registerForm.controls.surname.value,
      phoneNumber: this.registerForm.controls.phoneNumber.value,
      password: this.registerForm.controls.password.value,
      confirmPassword: this.registerForm.controls.confirmPassword.value,

    };


    this.email$ = this.customerService
    .register(registeredCustomer)
    .pipe(map(customer => customer.email));

    if (this.registerForm.invalid) {
      return;
    } else {
      setTimeout(() => this.router.navigate((['/customers'])), 5000);
    }

    alert('User successfully registered' + JSON.stringify(this.registerForm.value));

  }

}


前面:

    if (this.registerForm.invalid) {
      return;
    }
并检查布尔值是否
submitted=false
,但它没有产生所需的结果

提前感谢您的帮助

编辑:应用程序的Stackblitz链接


要激活路由,必须在app.module.ts(即根模块)中插入路由模块。 还可以将路由模块文件中的路由路径定义为:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
    {path: 'customers' , component: CustomersComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

另外,不要放弃包含
标记,因为路由成功后,子视图将在该标记处加载。

我们一直在开发一个库,该库可以轻松地处理表单,并且具有更高的类型安全性(对于TS和HTML!)。此库称为ngx子表单,您可以在此处找到它:

使用
ngx子表单
,我制作了你的应用程序的演示,你可以在这里尝试:

现在,一些解释

首先,我们想为您的表单定义一个合适的接口(键入safety以获得成功!):

然后我们创建应用程序所需的所有组件:
-
app/app.component.ts

-
app/registration/registration.component.ts

-
app/registration/registration form/registration form.component.ts

-
app/customers.component.ts

现在我们需要为我们的应用程序定义路由。我们的
app.module.ts
应该如下所示:

const ROUTES: Routes = [
  {
    path: '',
    redirectTo: '/registration',
    pathMatch: 'full'
  },
  {
    path: 'registration',
    component: RegistrationComponent
  },
  {
    path: 'customers',
    component: CustomersComponent
  },
];

@NgModule({
  imports: [BrowserModule, ReactiveFormsModule, RouterModule.forRoot(ROUTES)],
  declarations: [AppComponent, RegistrationFormComponent, RegistrationComponent, CustomersComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
应该是

RegistrationComponent
将充当智能组件。它将注入路由器并等待表单发送。该组件不想知道表单本身,只想知道已发送的对象

@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent {
  constructor(private router: Router) {}

  public register(registrationForm: RegistrationForm): void {
    // here you probably want to inject a `RegistrationService` instead of the `Router`
    // and call a method that will make an XHR call to your backend and on success
    // would do that `navigate` from the service too
    // for the sake of simplicity here I'm just doing the navigate directly
    this.router.navigate(['/customers']);
  }
}
及其HTML:

<app-registration-form (register)="register($event)"></app-registration-form>
注意事项如下:

  • export class RegistrationFormComponent扩展了NgxSubFormComponent
    我们正在扩展
    NgxSubFormComponent
    并传递表单接口。这将为我们提供许多实用程序和一些类型安全性

  • 方法
    getFormControls
    要求您基本上提供一个对象来创建表单。我认为这是不言自明的,因为它看起来就像创建
    FormGroup

  • getFormGroupControlOptions
    是由
    NgxSubFormComponent
    提供的一个钩子,允许您在
    FormGroup
    级别设置验证器或异步验证器

  • 最后,
    onSubmit
    方法是当用户单击
    Register
    按钮时调用的方法(一旦表单完全有效)

现在,缺少的最后一个部分是表单HTML(为了简单起见,我将只在响应中显示第一个字段和密码检查,因为两者之间的内容几乎相同)


填写下表以完成注册过程
用户名
用户名是必需的
...
确认密码
确认密码是必需的
密码必须匹配
登记
HTML中需要注意的事项:


  • 控制台中是否有错误?你确认你的路线定义正确了吗?@Narm,控制台已清除。我只收到当前已注册客户的字段{id:30,姓名:“马丁”,姓氏:“马丁”,电子邮件:“马丁。martin@o2.pl“}`如果在If/else中添加console.log()语句,它是否真的会进入else语句?另外,
    电子邮件$
    在哪里/如何使用?使用
    async
    管道?看起来括号太多了。尝试此
    this.router.navigate(['/customers'])
    添加stackblitz链接后,我将删除下一票。事实上,要想帮助你是不可能的,因为人们必须猜测你的应用程序中发生了什么,而不需要一点批评。我认为这不是Route的问题,因为到目前为止,我的AppRoutingModule.ts看起来像:
    const appRoutes:Routes=[{path:'customers',component:CustomerListComponent},{path:'registration',component:RegistrationComponent},{path:'**',重定向到:'notfound',pathMatch:'full'}];@NgModule({imports:[BrowserModule,RouterModule.forRoot(appRoutes,{onSameUrlNavigation:'reload'}),FormsModule],exports:[RouterModule]})导出类AppRoutingModule{}
    如果我错了,请提醒我您可以使用.navigateByUrl()方法进行绝对路径路由,而不是.navigate()。这可能会有所帮助
    const ROUTES: Routes = [
      {
        path: '',
        redirectTo: '/registration',
        pathMatch: 'full'
      },
      {
        path: 'registration',
        component: RegistrationComponent
      },
      {
        path: 'customers',
        component: CustomersComponent
      },
    ];
    
    @NgModule({
      imports: [BrowserModule, ReactiveFormsModule, RouterModule.forRoot(ROUTES)],
      declarations: [AppComponent, RegistrationFormComponent, RegistrationComponent, CustomersComponent],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    @Component({
      selector: 'app-registration',
      templateUrl: './registration.component.html',
      styleUrls: ['./registration.component.css']
    })
    export class RegistrationComponent {
      constructor(private router: Router) {}
    
      public register(registrationForm: RegistrationForm): void {
        // here you probably want to inject a `RegistrationService` instead of the `Router`
        // and call a method that will make an XHR call to your backend and on success
        // would do that `navigate` from the service too
        // for the sake of simplicity here I'm just doing the navigate directly
        this.router.navigate(['/customers']);
      }
    }
    
    <app-registration-form (register)="register($event)"></app-registration-form>
    
    @Component({
      selector: 'app-registration-form',
      templateUrl: './registration-form.component.html',
      styleUrls: ['./registration-form.component.css']
    })
    export class RegistrationFormComponent extends NgxSubFormComponent<RegistrationForm> {
      @Output() register: EventEmitter<RegistrationForm> = new EventEmitter();
    
      protected getFormControls(): Controls<RegistrationForm> {
        return {
          username: new FormControl(null, [Validators.required]),
          email: new FormControl(null, [Validators.required]),
          name: new FormControl(null, [Validators.required]),
          surname: new FormControl(null, [Validators.required]),
          phoneNumber: new FormControl(null, [Validators.required]),
          nip: new FormControl(null, [Validators.required]),
          password: new FormControl(null, [Validators.required]),
          confirmPassword: new FormControl(null, [Validators.required]),
        }
      }
    
      protected getFormGroupControlOptions(): FormGroupOptions<RegistrationForm> {
        return {
          validators: [
            formGroup => {
              if (formGroup.value.password !== formGroup.value.confirmPassword) {
                return {
                  passwordsMustMatch: true,
                };
              }
    
              return null;
            },
          ],
        };
      }
    
      public onSubmit(): void {
        this.register.emit(this.formGroupValues)
      }
    }
    
    <div class="jumbotron">
      <div class="container">
        <div class="row">
          <div class="col-md-6 offset-md-3">
            <h3>Fill in the form below to complete the registration process</h3>
            <form [formGroup]="formGroup" (ngSubmit)="onSubmit()">
              <div class="form-group">
                <label>Username</label>
                <input type="text" [formControlName]="formControlNames.username" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.username }" />
                <div *ngIf="formGroupErrors && formGroupControls.username.touched" class="invalid-feedback">
                  <div *ngIf="formGroupErrors?.username?.required">Username is required</div>
                </div>
              </div>
    
              ...
    
    
              <div class="form-group">
                <label>Confirm Password</label>
                <input type="text" [formControlName]="formControlNames.confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.confirmPassword }" />
                <div *ngIf="formGroupErrors && formGroupControls.confirmPassword.touched" class="invalid-feedback">
                  <div *ngIf="formGroupErrors?.confirmPassword?.required">Confirm Password is required</div>
                  <div *ngIf="formGroupErrors?.formGroup?.passwordsMustMatch">Passwords must match</div>
                </div>
              </div>
    
              <div class="form-group">
                <button class="btn btn-primary" [disabled]="formGroup.invalid">Register</button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>