【问题标题】:Custom Validator Reactive Form Ionic自定义验证器反应形式离子
【发布时间】:2021-07-06 00:35:13
【问题描述】:

这是我第一次使用自定义验证器。我遵循了本指南https://ionicthemes.com/tutorials/about/forms-and-validation-in-ionic。基本上我想检查用户名是否已被使用,如果是,则更新配置文件按钮未启用。但它不起作用,如果我尝试在表单中输入一个已经存在于 firebase 实时数据库中的用户名,则该按钮已启用,但在控制台中我收到消息“username già in uso”。我对 UsernameValidator 类做错了吗?

import { FormControl } from '@angular/forms';
import * as firebase from 'firebase';
export class UsernameValidator {
    static validUsername(fc: FormControl){
        firebase.database().ref().child("users").orderByChild("username")
        .equalTo(fc.value)
        .once("value",snapshot => {
          if (snapshot.exists()){
            console.log("username già in uso")
            return ({validUsername: false});         
            }
          else
            return (null);           
        });
    }
}

这是我定义表单组和验证器的地方:

  constructor(private route: ActivatedRoute, private router: Router, 
              public pfService: ProfileService, public fb: FormBuilder,
              public authService: AuthenticationService) 
  {
    this.id = this.authService.userData.uid;
    //Underscore and dot can't be next to each other (e.g user_.name).
    //Underscore or dot can't be used multiple times in a row (e.g user__name / user..name).
    this.validPattern = "^(?=.{6,20}$)(?!.*[_.]{2})[a-z0-9._]+$"; 
    this.validPatternName = "^[a-z]{3,10}$";
    this.userForm = fb.group({
      txtUsername:  ["",[Validators.required,Validators.pattern(this.validPattern),
                                                  UsernameValidator.validUsername]],
      txtName:     ["",[Validators.required,Validators.pattern(this.validPatternName)]],
    });
  };

这是 HTML 代码:

<form [formGroup]="userForm" (ngSubmit)="updateForm()" >
  <ion-item>
    <ion-label class="form-control" position="floating">Userame</ion-label>
    <ion-input formControlName="txtUsername" type="text" ></ion-input>
    <span [hidden]="userForm.controls.txtUsername.valid || userForm.controls.txtUsername.pristine">Lunghezza tra 6 e 20 caratteri</span>
  </ion-item>

  <ion-item>
    <ion-label class="form-control" position="floating">Name</ion-label>
    <ion-input formControlName="txtName" type="text" > </ion-input>
    <span [hidden]="userForm.controls.txtName.valid || userForm.controls.txtName.pristine">Lunghezza tra 6 e 20 caratteri</span>   
  </ion-item>

  <ion-row>
    <ion-col>
      <ion-button type="submit" *ngIf="userForm.controls.txtUsername.valid && userForm.controls.txtName.valid " color="primary" shape="full" expand="block">Update Profile</ion-button>
    </ion-col>
  </ion-row>
</form>

【问题讨论】:

    标签: ionic-framework customvalidator


    【解决方案1】:

    首先,我建议您的验证器返回:

     return ({validUsername: true});  
    

    如果您想在每次输入字符时检查验证器状态,我建议您在表单声明后添加构造器:

     this.userForm .valueChanges.subscribe(()=> {
    console.log(this.userForm.getError('validUsername'))
    })
    

    另外,也许你的验证器不会返回任何东西,因为它会卡在快照中,你会知道你的 userForm.getError('validUsername') 是否仍然返回 null,即使你得到“username già in uso”。

    【讨论】:

    • 您好帕特里克,感谢您的回复。我修改了验证器返回并添加了您所说的内容。你是对的,即使有“用户名 già in uso”,它也会返回 null。奇怪,怎么让它不卡在快照里?
    • 嗨@ChrisCv,你看到我的回答了吗?
    • 嗨帕特里克,是的,谢谢你,我已经接受了你的回答
    【解决方案2】:

    由于您的 firebase 查询是异步函数,请尝试以下操作:

     static validUsername(fc: FormControl){
            firebase.database().ref().child("users").orderByChild("username")
            .equalTo(fc.value)
            .once("value",async snapshot => {
              if (snapshot.exists()){
                console.log("username già in uso")
               return await ({validUsername: true});         
                }
              else
                return (null);           
            });
        }
    

    static validUsername(fc: FormControl){
         let bool:boolean =this.getSnapshot(fc.value)
              if(bool===true)
    
               return  ({validUsername: true});         
                }
              else{
                return (null); 
                 }          
            });
        }
    async getSnapshot(value:string):boolean{
    let bool:boolean
     await firebase.database().ref().child("users").orderByChild("username")
            .equalTo(fc.value)
            .once("value",snapshot => {
              if (snapshot.exists()){
                bool=true
                console.log("username già in uso")               
                }
              else{
                  bool=false
                 }
                       
            });
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 2017-10-06
      • 2018-12-29
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多