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

Angular 4中timepicker失焦时获取值并比较的问题

解决Angular Timepicker无法获取值及焦点失焦时比较时间的问题

我明白你现在遇到的麻烦了——两个timepicker字段总是拿不到值,输出都是undefined,还想在字段失去焦点时立刻比较时间大小对吧?咱们一步步来把问题捋清楚,然后搞定它:

一、先揪出导致undefined的核心问题

你的代码里有几个关键的小问题,直接导致了值获取异常:

  1. 混用formControlName和ngModel:在Angular响应式表单里,这俩不能同时用!它们会互相干扰,导致表单值同步混乱,这是你拿到undefined的主要原因。
  2. 依赖keyup事件赋值不可靠:你把时间值存在timeStart和timeSegment里,但timepicker的操作不一定都是键盘输入(比如点击选择时间),这会导致类属性和真实表单值不同步。
  3. 时间比较逻辑有漏洞:直接用this.timeSegment < this.timeStart的方式不对,而且代码里还写错了变量名(this.startTime应该是this.timeStart)。

二、修正后的完整代码实现

1. TypeScript代码(.ts)

咱们去掉冗余的ngModel绑定,直接从表单控件里拿最新值,同时优化时间比较的逻辑:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponent implements OnInit {
  isMeridian = false;
  showSpinners = false;
  mySummaryForm: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
    // 初始化表单,给控件设置初始值(避免一开始就是undefined)
    this.mySummaryForm = this.fb.group({
      startTime: [''],
      segmentTime3: ['']
    });
  }

  // 保留keyup事件用于调试,实际业务中可以按需移除
  onKeyTime(event) {
    console.log("onKeyTime :" + this.mySummaryForm.get('startTime').value);
  }

  onKeySeg(event) {
    console.log("onKeySeg : " + this.mySummaryForm.get('segmentTime3').value);
  }

  checkTimeValue() {
    console.log("checkTimeValue :");
    // 直接从表单控件获取最新的时间值
    const startTime = this.mySummaryForm.get('startTime').value;
    const segmentTime = this.mySummaryForm.get('segmentTime3').value;

    // 先判断值是否存在,避免空值导致报错
    if (!startTime || !segmentTime) {
      console.log("请先选择完整的时间哦");
      return;
    }

    // 把时间转成Date对象再比较(如果timepicker返回的是字符串,需要先解析)
    const startDate = new Date(startTime);
    const segmentDate = new Date(segmentTime);

    if (segmentDate < startDate) {
      console.log(`时间段 ${segmentDate.toLocaleTimeString()} 早于开始时间 ${startDate.toLocaleTimeString()}`);
      // alert("time segment should be later than start time.");
    } else {
      console.log(`时间段 ${segmentDate.toLocaleTimeString()} 晚于开始时间 ${startDate.toLocaleTimeString()}`);
      // alert("good choice!");
    }
  }

  submitMe(form: FormGroup) {
    // 表单提交逻辑
    console.log(form.value);
  }
}

2. HTML代码(.html)

移除ngModel相关绑定,只保留响应式表单需要的formControlName,确保事件绑定正确:

<form [formGroup]="mySummaryForm" (ngSubmit)="submitMe(mySummaryForm)">
  <label for="startTime">
    Start time : {{mySummaryForm.get('startTime').value | date: 'shortTime'}}
    <timepicker 
      formControlName="startTime" 
      [showMeridian]="isMeridian" 
      [showSpinners]="showSpinners" 
      (keyup)="onKeyTime($event)"
      #startTime 
      required>
    </timepicker>
  </label>

  <label for="segmentTime3">
    Segment time : {{mySummaryForm.get('segmentTime3').value | date: 'shortTime'}}
    <timepicker 
      formControlName="segmentTime3" 
      [showMeridian]="isMeridian" 
      [showSpinners]="showSpinners" 
      (keyup)="onKeySeg($event)" 
      (focusout)="checkTimeValue()"
      #segmentTime3 
      required>
    </timepicker>
  </label>

  <!-- 可以添加提交按钮 -->
  <button type="submit">提交</button>
</form>

三、优化点说明

  • 去掉ngModel:响应式表单里formControlName已经能完成双向绑定,混用会导致状态混乱,这是解决undefined的关键。
  • 直接从表单取值:在checkTimeValue里直接通过form.get('controlName').value拿值,确保每次都是最新的真实值,不用再依赖keyup事件赋值。
  • 时间比较更靠谱:转成Date对象再比较,避免字符串比较的逻辑错误;同时增加空值判断,防止报错。
  • 调试更清晰:用toLocaleTimeString()输出易读的时间格式,方便你看日志排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:21:01