【问题标题】:Angular form validation: compare two fields角度表单验证:比较两个字段
【发布时间】:2018-02-21 04:58:19
【问题描述】:

在 Angular 4 应用程序中,如何验证表单的两个字段进行比较?

例如,假设我的表单有一个startDate 和一个endDate 日期字段,我想确保endDate 必须大于startDate

【问题讨论】:

  • 您是否尝试过通过 [(ngModel)] 访问表单上的两个值,然后比较两个值?
  • @ShinDarth 下面我的回答对你有帮助???
  • @Robert 感谢您的回答,但我使用了 amal 的解决方案,看起来更简单

标签: forms angular validation angular-forms angular-validation


【解决方案1】:

试试这个

export class validationComponent implements OnInit {
     private testForm:FormGroup;

     constructor(private fb: FormBuilder) {

     }

     ngOnInit() {
         this.testForm = this.fb.group({
           'startDate': ['', [Validators.required]],
           'endDate': ['', [Validators.required]]
        });

       this.subscribeDateChanges();
    }

    subscribeDateChanges() {
        const startDateChanges = (<any>this.testForm).controls.startDate.valueChanges;
        const endDateChanges = (<any>this.testForm).controls.endDate.valueChanges;

        startDateChanges.subscribe(start => {
             this.testForm.controls['endDate'].
               setValidators(
                [Validators.required,
                CustomValidators.minDate(this.toYYYYMMDD(start))]);
        this.validateDates();
       });

       endDateChanges.subscribe(end => {
               this.validateDates();
         });
     }

   dateError: boolean = false;
   validateDates(): void{
       let startDate = this.testForm.controls['startDate'].value;
       let endDate = this.testForm.controls['endDate'].value;
       if(endDate && startDate){
           this.dateError = endDate <= startDate;
        }
    }

   toYYYYMMDD(d:Date): string {
       d = new Date(d)
       var yyyy = d.getFullYear().toString();
       var mm = (d.getMonth() + 101).toString().slice(-2);
       var dd = (d.getDate() + 100).toString().slice(-2);
       return yyyy + '-' +  mm + '-'  + dd;
   }

基于 dateError 布尔值显示错误消息

【讨论】:

    【解决方案2】:

    当您想要实现包含一个或多个同级(表单)控件的验证时,您必须在同级控件的上一级/之上定义验证器函数。例如:

    ngOnInit() {
        this.form = this.formbuilder.group({
            'startDate': ['', [<control-specific - validations >]],
            'endDate': ['', [<control-specific - validations >]]
        }, { validator: checkIfEndDateAfterStartDate });
    }
    

    然后在组件类的定义之外(在同一个文件中),同样定义函数checkIfEndDateAfterStartDate

    export function checkIfEndDateAfterStartDate (c: AbstractControl) {
        //safety check
        if (!c.get('startDate').value || !c.get('endDate').value) { return null }
        // carry out the actual date checks here for is-endDate-after-startDate
        // if valid, return null,
        // if invalid, return an error object (any arbitrary name), like, return { invalidEndDate: true }
        // make sure it always returns a 'null' for valid or non-relevant cases, and a 'non-null' object for when an error should be raised on the formGroup
    }
    

    通过将错误标志(此处为invalidEndDate)添加到true 到该FormGroup 的错误对象,此验证将使FormGroup 无效。如果您想在任何同级控件上设置特定错误,则可以使用c.get('endDate').setErrors({ invalidEndDate: true }) 之类的东西手动设置formControl 上的错误标志。如果您这样做,请确保通过将错误设置为 null 来清除它们的有效大小写,例如 c.get('endDate').setErrors(null)

    可以看到类似验证的现场演示here

    【讨论】:

    • 我认为您不需要导出检查功能。另外,为什么您将c 声明为AbstractControl 而不仅仅是FormGroup
    • 是的,如果函数在同一个文件中,您不一定必须“导出”该函数。我将它声明为AbstractControl,因为它是FormGroups(以及FormControls 和FormArrays)的基类。这样做没有坏处。还可以帮助您使用该类“打字稿”中定义的所有属性。
    • @ShinDarth 你能用 .ts 发布你的代码 .html 吗?我很着迷同样的情况。提前谢谢:)
    猜你喜欢
    • 2019-04-24
    • 2015-02-07
    • 2018-08-18
    • 1970-01-01
    • 2015-07-08
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多