You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17 Material响应式表单时间输入范围验证实现求助

Angular 17 + Material 时间区间验证实现方案

核心实现要点

  • 统一表单控件名称,确保HTML与TS逻辑一致
  • 自定义单个时间的区间验证函数
  • 添加表单级交叉验证,保证结束时间不早于起始时间
  • 结合Material的mat-error组件显示精准错误提示

修改后的模板文件 (my-time.component.html)

<form [formGroup]="timeFormGroup" (ngSubmit)="save()">
  <div style="display:flex; gap: 16px;">  
    <mat-form-field style="width: 120px;" appearance="outline">                         
      <mat-label>Min Hour</mat-label>
      <input type="time" matInput formControlName="minHour">
      <mat-error *ngIf="timeFormGroup.get('minHour')?.hasError('required')">
        请输入起始时间
      </mat-error>
      <mat-error *ngIf="timeFormGroup.get('minHour')?.hasError('timeOutOfRange')">
        起始时间需在09:00-13:00之间
      </mat-error>
    </mat-form-field>                           

    <mat-form-field style="width: 120px;" appearance="outline">
      <mat-label>Max Hour</mat-label>
      <input type="time" matInput formControlName="maxHour">
      <mat-error *ngIf="timeFormGroup.get('maxHour')?.hasError('required')">
        请输入结束时间
      </mat-error>
      <mat-error *ngIf="timeFormGroup.get('maxHour')?.hasError('timeOutOfRange')">
        结束时间需在09:00-13:00之间
      </mat-error>
      <mat-error *ngIf="timeFormGroup.hasError('maxLessThanMin')">
        结束时间不能早于起始时间
      </mat-error>
    </mat-form-field>
  </div>

  <div style="margin-top: 16px;">
    <button mat-flat-button color="accent" type="submit" [disabled]="timeFormGroup.invalid">Save</button>
  </div>
</form>

修改后的组件逻辑 (my-time.component.ts)

import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, Validators, AbstractControl, ValidationErrors } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatButtonModule } from '@angular/material/button';

@Component({
  selector: 'app-my-time',
  templateUrl: './my-time.component.html',
  styleUrls: ['./my-time.component.scss'],
  standalone: true, // 独立组件需添加此项,模块式组件可移除并在对应模块中导入依赖
  imports: [
    CommonModule,
    ReactiveFormsModule,
    MatInputModule,
    MatFormFieldModule,
    MatButtonModule
  ]
})
export class MyTimeComponent implements OnInit {

  timeFormGroup = this.fb.group({
    minHour: ['', [Validators.required, this.timeRangeValidator]],
    maxHour: ['', [Validators.required, this.timeRangeValidator]]
  }, { validators: this.minMaxTimeValidator });

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void { }

  // 验证单个时间是否在09:00-13:00区间内
  private timeRangeValidator(control: AbstractControl): ValidationErrors | null {
    const timeValue = control.value;
    if (!timeValue) return null;

    // 将时间字符串转换为分钟数,简化数值比较
    const [hours, minutes] = timeValue.split(':').map(Number);
    const totalMinutes = hours * 60 + minutes;
    const minAllowed = 9 * 60; // 09:00对应的分钟数
    const maxAllowed = 13 * 60; // 13:00对应的分钟数

    if (totalMinutes < minAllowed || totalMinutes > maxAllowed) {
      return { timeOutOfRange: true };
    }
    return null;
  }

  // 验证结束时间不早于起始时间
  private minMaxTimeValidator(group: AbstractControl): ValidationErrors | null {
    const minHour = group.get('minHour')?.value;
    const maxHour = group.get('maxHour')?.value;

    if (!minHour || !maxHour) return null;

    const [minH, minM] = minHour.split(':').map(Number);
    const [maxH, maxM] = maxHour.split(':').map(Number);
    const minTotal = minH * 60 + minM;
    const maxTotal = maxH * 60 + maxM;

    if (maxTotal < minTotal) {
      return { maxLessThanMin: true };
    }
    return null;
  }

  save() {
    if (this.timeFormGroup.valid) {
      console.log(this.timeFormGroup.value);
      // 此处添加实际保存逻辑
    }
  }
}

关键说明

  1. 控件名称统一:修正了原代码中HTML与TS表单控件名称不一致的问题,确保数据绑定正常。
  2. 时间区间验证:通过将时间转换为分钟数,避免字符串比较的复杂度,精准判断是否在09:00-13:00范围内。
  3. 交叉验证:表单级验证器确保结束时间不会早于起始时间,覆盖业务逻辑的完整性。
  4. 错误提示:利用Material的mat-error组件,根据不同错误类型显示对应提示,且仅在控件被触摸或表单提交后触发显示(符合Material默认交互逻辑)。
  5. 提交控制:提交按钮通过[disabled]属性绑定表单有效性,防止无效提交。

内容的提问来源于stack exchange,提问作者user1912316

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:05:19