Angular 4中timepicker失焦时获取值并比较的问题
解决Angular Timepicker无法获取值及焦点失焦时比较时间的问题
我明白你现在遇到的麻烦了——两个timepicker字段总是拿不到值,输出都是undefined,还想在字段失去焦点时立刻比较时间大小对吧?咱们一步步来把问题捋清楚,然后搞定它:
一、先揪出导致undefined的核心问题
你的代码里有几个关键的小问题,直接导致了值获取异常:
- 混用
formControlName和ngModel:在Angular响应式表单里,这俩不能同时用!它们会互相干扰,导致表单值同步混乱,这是你拿到undefined的主要原因。 - 依赖
keyup事件赋值不可靠:你把时间值存在timeStart和timeSegment里,但timepicker的操作不一定都是键盘输入(比如点击选择时间),这会导致类属性和真实表单值不同步。 - 时间比较逻辑有漏洞:直接用
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
相关产品推荐
相关产品推荐

