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中的子窗体控件添加错误,而不使子控件静音';我们自己的验证器 this.form=this.fb.array([ 这个.fb.group({ 用户名:[空,验证程序。必需] }), 这个.fb.group({ 用户名:[空,验证程序。必需] }), ... ],uniqueUsernameValidator) const uniqueUsernameValidator=控件=>{ //找到副本 //当标记错误时 control.get('0.username').setErrors(IfthereisError)//其中'IfthereisError'可以为null }_Angular_Validation_Angular Reactive Forms_Angular Forms_Angular Validation - Fatal编程技术网

如何向angular中的子窗体控件添加错误,而不使子控件静音';我们自己的验证器 this.form=this.fb.array([ 这个.fb.group({ 用户名:[空,验证程序。必需] }), 这个.fb.group({ 用户名:[空,验证程序。必需] }), ... ],uniqueUsernameValidator) const uniqueUsernameValidator=控件=>{ //找到副本 //当标记错误时 control.get('0.username').setErrors(IfthereisError)//其中'IfthereisError'可以为null }

如何向angular中的子窗体控件添加错误,而不使子控件静音';我们自己的验证器 this.form=this.fb.array([ 这个.fb.group({ 用户名:[空,验证程序。必需] }), 这个.fb.group({ 用户名:[空,验证程序。必需] }), ... ],uniqueUsernameValidator) const uniqueUsernameValidator=控件=>{ //找到副本 //当标记错误时 control.get('0.username').setErrors(IfthereisError)//其中'IfthereisError'可以为null },angular,validation,angular-reactive-forms,angular-forms,angular-validation,Angular,Validation,Angular Reactive Forms,Angular Forms,Angular Validation,不知何故,uniqueUsernameValidator正在使子表单字段指定的required验证无效。如何解决此问题?为控件创建自定义验证程序时,应实现: 实现可以如下所示: const uniqueUsernameValidator = control => { const ifThereIsAnError = /* your logic .. find duplicate */ if(!ifThereIsAnError) { return null }

不知何故,
uniqueUsernameValidator
正在使子表单字段指定的
required
验证无效。如何解决此问题?

为控件创建自定义验证程序时,应实现:

实现可以如下所示:

const uniqueUsernameValidator = control => {
  const ifThereIsAnError = /* your logic .. find duplicate */
  
  if(!ifThereIsAnError) {
    return null
  }

  return { unique: true  } 

}
在你的情况下,我想你的意思是
setErrors
,而不是
setError
?使用AbstractControl的错误设置程序时,您将使用
setErrors
覆盖所有错误。如果要保留解决方案而不使用,则应在设置新错误之前获取错误:

const uniqueUsernameValidator = control => {
  const errors: ValidationErrors = this.control.errors;
  const keyNameOfYourError = 'unique';

  // reset the last error before revalidating
  if (errors && errors[keyNameOfYourError]) {
    delete errors[keyNameOfYourError];
  }

  // ifThereIsAnError = execute your logic ... find duplicate
  if (ifThereIsAnError) {
    errors[keyNameOfYourError] = true;
    this.control.setErrors(errors);
  }
}
但我建议您使用该实现。

尝试下面的方法


这将验证by user中提供的用户名是否都是唯一的

我将这样解决它:

const uniqueUsernameValidator = control => {
  const ifThereIsAnError = /* your logic .. find duplicate */
  
  if(!ifThereIsAnError) {
    return null
  }

  return { unique: true  } 

}

我的窍门

  • 我喜欢验证时出现错误的地方。因此,控件本身正在处理其
    错误
    属性

  • 确保你的控件知道什么时候发生了变化

    this.sub=this.usernamesArr.valueChanges.subscribe(=>updateControl(this.usernamesArr))

  • 我们需要访问用户名控件中的formArray值。装订
    我们可以访问它

    uniqueInArray=uniqueInArray.bind(这个)

  • (从stackblitz复制的代码)

    html
    
    {{usernamesArr.controls[i].controls.username.errors | json}
    添加
    
    ts
    从“@angular/core”导入{Component};
    进口{
    造模工,
    FormGroup,
    形式上,
    FormControl,
    验证器,
    抽象控制
    }从“@angular/forms”;
    从“rxjs”导入{Subscription};
    const uniqueInArray=函数(
    控件:抽象控件
    ):{uniqueInArray:string}空{
    常量值=control.value;
    const arr=this.usernamesArr.value为{username:string}[];
    如果(value==null | | value.length==0 | | arr==null | | arr.length<2){
    返回null;
    }
    返回arr.map(\u=>\ uUserName).filter(\u=>\ u==value).length>1
    ?{uniqueInArray:`${value}已存在。`}
    :null;
    };
    const updateControls=函数(控件:FormArray):null{
    control.controls.map((c:FormGroup)=>
    c、 controls.username.updateValueAndValidity({
    只有你自己:真的,
    emit事件:false
    })
    );
    返回null;
    };
    @组成部分({
    选择器:“我的应用程序”,
    templateUrl:“./app.component.html”,
    样式URL:[“/app.component.css”]
    })
    导出类AppComponent{
    分:认购;
    usernamesArr:FormArray;
    uniqueInArray=uniqueInArray.bind(this);
    构造函数(私有formBuilder:formBuilder){}
    恩戈尼尼特(){
    this.usernamesArr=newformarray([]);
    this.sub=this.usernamesArr.valueChanges.subscribe(\u=>
    UpdateControl(this.usernamesArr)
    );
    }
    createItem():抽象控件{
    返回新表单组({
    用户名:new FormControl(“,[Validators.required,this.uniqueInArray])
    });
    }
    addItem():void{
    this.usernamesArr.push(this.createItem());
    }
    恩贡德斯特罗(){
    此.sub.取消订阅();
    }
    }
    
    回答设置错误而不可能消除其他验证器错误这一更普遍的问题:

    // Add - retaining existing
    const errors = {
        ...control.errors,
        myError: myValue
      };
    control.setErrors(errors);
    
    // Remove - only the one we care about
    const errors = { ...control.errors };
    delete errors.myError;
    control.setErrors(Object.keys(errors).length ? errors : null);
    

    不要使用setErrors。如果一切正常,自定义验证器必须返回null,如果存在重复项,则必须返回一个对象。您可以有:this.form.errors、this.form.at(0).get('userName')。错误和/或this.form.at(1).get('userName')。错误正如其他人所说,您是否希望以这种方式设置错误是有争议的。我想,它的预期用途是返回一个对象或null,但有一次我需要与两个控件交互,因此使用了formgroup验证器,我需要在UI中显示错误,这对我来说,将错误放在控件而不是表单上是有意义的。因此,在我看来,在验证器中调用setErrors有一些用例——尽管比较少见。
    <div [formGroup]="usernamesArr"
      *ngFor="let item of usernamesArr.controls; let i = index;">
      <div [formGroupName]="i">
        <input formControlName="username" [placeholder]="'username' + i">
        
        <pre style="color: red">
          {{usernamesArr.controls[i].controls.username.errors | json}}
        </pre>
    
      </div>
    </div>
    
    <button (click)="addItem()">Add</button>
    
    import { Component } from "@angular/core";
    import {
      FormBuilder,
      FormGroup,
      FormArray,
      FormControl,
      Validators,
      AbstractControl
    } from "@angular/forms";
    import { Subscription } from "rxjs";
    
    const uniqueInArray = function(
      control: AbstractControl
    ): { uniqueInArray: string } | null {
    
      const value = control.value;
      const arr = this.usernamesArr.value as { username: string }[];
      if (value == null || value.length === 0 || arr == null || arr.length < 2) {
        return null;
      }
    
      return arr.map(_ => _.username).filter(_ => _ == value).length > 1
        ? { uniqueInArray: `${value} already exists.` }
        : null;
    };
    
    const updateControls = function(control: FormArray): null {
    
      control.controls.map((c: FormGroup) =>
        c.controls.username.updateValueAndValidity({
          onlySelf: true,
          emitEvent: false
        })
      );
      return null;
    };
    
    @Component({
      selector: "my-app",
      templateUrl: "./app.component.html",
      styleUrls: ["./app.component.css"]
    })
    export class AppComponent {
    
      sub: Subscription;
    
      usernamesArr: FormArray;
    
      uniqueInArray = uniqueInArray.bind(this);
    
      constructor(private formBuilder: FormBuilder) {}
    
      ngOnInit() {
        this.usernamesArr = new FormArray([]);
    
        this.sub = this.usernamesArr.valueChanges.subscribe(_ =>
          updateControls(this.usernamesArr)
        );
      }
    
      createItem(): AbstractControl {
        return new FormGroup({
          username: new FormControl("", [Validators.required, this.uniqueInArray])
        });
      }
    
      addItem(): void {
        this.usernamesArr.push(this.createItem());
      }
    
      ngOnDestroy() {
        this.sub.unsubscribe();
      }
    }
    
    // Add - retaining existing
    const errors = {
        ...control.errors,
        myError: myValue
      };
    control.setErrors(errors);
    
    // Remove - only the one we care about
    const errors = { ...control.errors };
    delete errors.myError;
    control.setErrors(Object.keys(errors).length ? errors : null);