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

Angular问题:独立输入框下ngx-bootstrap时间选择器无法更新值

问题:ngx-bootstrap时间选择器无法更新输入框值

我在用ngx-bootstrap的时间选择器,当前实现代码如下:

HTML代码

<ng-template #quantityTimeAdvancedPicker>
  <timepicker
  [showMeridian]="false"
  [showSeconds]="true"
  [minuteStep]="1"
  [secondsStep]="1"
  [ngModelOptions]="{ standalone: true }"
  [ngModel]="
    data.quantity | secondsInputsToDate
  "
  ></timepicker>
</ng-template>
<input
  class="form-control text-center"
  type="text"
  [popover]="quantityTimeAdvancedPicker"
  [outsideClick]="true"
  placement="bottom"
  [ngModelOptions]="{ standalone: true }"
  [ngModel]="
    data.quantity
    | secondsInputsToDate
    | date : 'HH:mm:ss'
  "
 (ngModelChange)="setDirty(true)"
/>

SecondsInputsToDatePipe管道代码

transform(seconds: number): Date {
  const date = moment(
    seconds * 1000 + new Date().getTimezoneOffset() * 60000
    ).toDate();

  return date;
}

时间选择器输入表单

目前功能看似正常,但时间选择器无法更新输入框的值,导致没法给quantity设置新值。对比了我用ngx-mask的类似实现(能正常工作),怀疑问题和[ngModelOptions]="{ standalone: true }"配置有关。

正常工作的ngx-mask实现代码

HTML代码

<input
  [ngModelOptions]="{ standalone: true }"
  [ngModel]="data.quantity | secondsToHms"
  (ngModelChange)="
  data.quantity = $event; setDirty(true)"
  type="text"
  class="form-control text-center"
  placeholder="00:00:00"
  mask="00:m0:s0"
/>

SecondsToHmsPipe管道代码

transform(seconds: number): string {
  const minutes = Math.floor(seconds / 60); //分钟
  const secs = seconds % 60; //秒
  const hours = Math.floor(minutes / 60); //小时
  const mins = minutes % 60; //分钟

  return (
    '' +
    (hours < 10 ? hours.toString().padStart(2, '0') : hours.toString()) +
    mins.toString().padStart(2, '0') +
    secs.toString().padStart(2, '0')
  );
}

解决方法

核心问题是时间选择器只做了单向绑定,没有把选择的日期转换回秒数同步到data.quantity,输入框的ngModel依赖data.quantity,所以自然不会更新。

步骤1:给timepicker添加ngModelChange事件监听

修改timepicker部分的代码,添加(ngModelChange)事件,把选择的日期转换为秒数后更新data.quantity:

<ng-template #quantityTimeAdvancedPicker>
  <timepicker
    [showMeridian]="false"
    [showSeconds]="true"
    [minuteStep]="1"
    [secondsStep]="1"
    [ngModelOptions]="{ standalone: true }"
    [ngModel]="data.quantity | secondsInputsToDate"
    <!-- 新增:监听时间选择变化,同步到data.quantity -->
    (ngModelChange)="updateQuantityFromDate($event)"
  ></timepicker>
</ng-template>

步骤2:在组件类中实现转换方法

添加updateQuantityFromDate方法,将选择的日期转换为秒数(注意抵消时区偏移,和管道逻辑对应):

updateQuantityFromDate(selectedDate: Date): void {
  // 反向转换:日期转秒数,抵消时区偏移
  const totalMilliseconds = selectedDate.getTime() - new Date().getTimezoneOffset() * 60000;
  this.data.quantity = Math.floor(totalMilliseconds / 1000);
  // 标记为脏值
  this.setDirty(true);
}

原理说明

原来的ngx-mask实现中,直接在(ngModelChange)里更新了data.quantity,所以输入框能同步变化。而时间选择器的实现缺少了这个反向同步的步骤,导致data.quantity始终是旧值,输入框的管道就能拿到新值并更新显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:37:53