antd的timePicker.RangePicker设置结束时间不可早于开始时间

本文档介绍如何在Ant Design的TimePicker组件中,通过自定义`disabledHours`和`disabledMinutes`函数,以及`onCalendarChange`回调来实现结束时间不能早于开始时间的限制。当选择开始时间后,禁用所有晚于开始时间的小时和分钟;反之,选择结束时间后,禁用所有早于结束时间的小时和分钟。在某些情况下,`disabledTime`API未按预期工作,因此使用了替代方法。

antd当 结束时间小于结束时间时,会将俩个时间置换,不能满足需求啊

api中disabledTime不知为啥不触发。。。待解决

利用onCalendarChange方法和disabledHours、disabledMinutes去实现效果

代码如下

import { TimePicker } from 'antd'

const [disabledHourValue, setDisabeledHourValue] = useState([]) // 不能选择的小时
const [hourNum, setHourNum] = useState(0) // 已选择的时间的 小时数

const [minuteNum, setMinuteNum] = useState(0)  // 已选择的时间的 分钟数

const [selectType, setSelectType] = useState() // 已选择的时间的类型

const disabledHoursFun = () => {

  return disabledHourValue

}
const disabledMinutesFun = selectedHour => {
    let disabledValue = []
    if (selectType === 'start') {
      if (selectedHour === hourNum) {
        for (let i = 0; i < 60; i++) {
          if (i > minuteNum) {
            disabledValue.push(i)
          }
        }
      }
    } else if (selectType === 'end') {
      if (selectedHour === hourNum) {
        for (let i = 0; i < 60; i++) {
          if (i < minuteNum) {
            disabledValue.push(i)
          }
        }
      }
    }
    return disabledValue
}
const dealTimeData = (type, time) => {
    let timeArr = time.split(':')
    let hour = Number(timeArr[0])
    let minute = Number(timeArr[1])
    setHourNum(hour)
    setMinuteNum(minute)
    setSelectType(type)
    let disabledHourArr = []
    if (type === 'start') {
      for (let i = 0; i < 24; i++) {
        if (i > hour) {
          disabledHourArr.push(i)
        }
      }
    } else if (type === 'end') {
      for (let i = 0; i < 24; i++) {
        if (i < hour) {
          disabledHourArr.push(i)
        }
      }
    }
    return disabledHourArr
}
const changeRangeTime = (dates, dateStrings, info) => {
    if (dateStrings[0] === '' && dateStrings[1] === '') {
      setDisabeledHourValue([])
      return
    }
    let startTime = dateStrings[0]
    let endTime = dateStrings[1]
    if (info.range === 'start') {
      if (startTime !== '') {
        let data = dealTimeData('end', startTime)
        setDisabeledHourValue(data)
      }
    } else if (info.range === 'end') {
      if (endTime !== '') {
        let data = dealTimeData('start', endTime)
        setDisabeledHourValue(data)
      }
    }
}



<TimePicker.RangePicker

inputReadOnly

format="HH:mm"

disabledHours={disabledHoursFun}

disabledMinutes={disabledMinutesFun}

onCalendarChange={changeRangeTime}

/>

<think>好的,用户的问题是关于如何在Ant Design的TimePicker.RangePicker组件中防止用户重新选择已选中的时间范围。我需要先理解用户的具体需求。他们希望用户一旦选择了某个时间段后,再次打开选择器时,之前选中的时间段不能被修改,或者某些时间段被禁用,避免重复选择。 首先,我需要回忆Ant Design的相关组件文档,特别是TimePicker.RangePicker的API。我记得有一个disabledTime属性,可以用来禁用特定时间。另外,可能还需要结合value和onChange事件来控制用户的选择。 接下来,用户提供的引用内容中提到了一些相关实现,比如设置默认值和使用moment处理时间。引用[1]中的代码展示了如何通过state管理开始结束时间,并在onChange时更新state。引用[2]提到了在打开选择器时清空日期,这可能与重置状态有关,但用户的需求是防止重新选择,所以可能需要相反的操作,即保持原有值不变。 用户可能需要的是在用户尝试重新选择时,保持原有的时间范围不变,或者禁用某些时间段。这时候,可能需要使用disabledTime属性来动态禁用除了已选时间外的其他时间。例如,在开始时间选择后,结束时间只能选择在开始时间之后,或者固定不允许修改已选的时间段。 另外,可能需要结合form的受控组件特性,通过设置value属性为固定的时间范围,并且在onChange时不更新state,从而阻止用户修改。但这样可能会让用户无法进行任何选择,需要找到一个平衡点。 考虑到用户引用的代码中使用了moment来处理时间,可能需要继续使用moment对象来管理时间范围。同时,在用户打开选择器时,可能需要设置默认值为已选的时间,而不是清空,这可能需要类似引用[2]中的hackValue方法,但目的相反。 可能的解决方案是:在用户选择时间后,将时间范围存储在state中,并在后续渲染时,将TimePicker.RangePicker的value固定为该时间范围。同时,在onChange事件中,不更新state,从而阻止用户修改。或者,使用disabledTime函数来禁用除了当前选择的时间之外的所有时间选项,这样用户无法选择其他时间。 但需要验证这种方法的可行性。例如,设置value为固定值,并且不处理onChange事件,可能会导致组件无法交互,或者出现错误。或者,在onChange时检查新选择的时间是否与原有时间相同,如果不同则阻止更新。 另一个思路是,在用户打开选择器时,强制将选择器的值重置为已选的时间,这样即使用户尝试修改,选择器也会自动跳回原来的值。这可以通过在onOpenChange事件中设置hackValue来实现,类似引用[2]中的方法,但设置的是原有值而非空数组。 例如,在onOpenChange中,当打开选择器时,将hackValue设置为当前的startTime和endTime,这样选择器显示的时间范围始终是之前选中的,用户无法修改。这可能需要结合state和hackValue来实现。 总结可能的步骤: 1. 使用受控组件,通过state管理startTime和endTime。 2.TimePicker.RangePicker的value属性中传入固定的时间范围。 3. 在onChange事件中,不更新state,或者检查新值是否与原值相同,若不同则阻止更新。 4. 使用onOpenChange事件,在打开选择器时强制设置当前值,防止用户修改。 需要测试这些方法的有效性,并确保组件的行为符合预期。例如,如果用户在打开选择器时看到的是已选时间,但无法选择其他时间,可能需要结合disabledTime来禁用所有其他时间选项,但这可能比较复杂。 另一种方法是完全禁用输入框,使其无法再次打开选择器,但这可能不符合用户的需求,因为用户可能仍需要查看时间范围,只是不能修改。 因此,最佳方案可能是在onChange时检查并阻止修改,或者在onOpenChange时重置为原值。结合引用中的例子,可以尝试在onOpenChange时设置hackValue为当前的时间范围,这样即使用户选择其他时间,选择器关闭后也会恢复原值。 例如,当用户打开选择器时,设置hackValue为当前时间,然后在选择器关闭时恢复。这样在打开期间,用户的选择不会生效,因为hackValue强制显示原值。 此外,可能需要使用form.setFieldsValue来强制表单的值保持不变,如引用[2]中所示,但用于保持原值而非清空。 最后,需要确保代码示例正确,包括使用moment处理时间,管理state,并在render中正确绑定value和onChange事件。</think>在Ant Design的TimePicker.RangePicker中防止用户重新选择已选时间范围,可以通过以下步骤实现: ### 解决方案 1. **受控组件模式**:通过状态管理已选时间范围,确保组件始终显示固定值。 2. **拦截选择操作**:在`onChange`事件中阻止状态更新,或验证新值是否与原有值一致。 3. **强制重置选择器**:在打开选择器时通过`hackValue`强制回显已选时间,避免修改。 ```javascript import { TimePicker } from 'antd'; import moment from 'moment'; const RangePicker = TimePicker.RangePicker; class FixedTimeRange extends React.Component { state = { selectedTime: [ moment().startOf('hour'), // 初始开始时间设为整点 moment().startOf('hour').add(30, 'minutes') // 初始结束时间+30分钟 ], hackValue: null }; // 打开选择器时强制回显已选时间 handleOpenChange = (open) => { if (open) { this.setState({ hackValue: this.state.selectedTime }); } else { this.setState({ hackValue: null }); } }; // 拦截时间修改操作 handleTimeChange = (time) => { const isSameRange = time && time[0]?.isSame(this.state.selectedTime[0]) && time[1]?.isSame(this.state.selectedTime[1]); // 仅允许选择与当前范围完全相同的值(实际禁用修改) if (isSameRange) { this.setState({ selectedTime: time }); } }; render() { return ( <RangePicker value={this.state.hackValue || this.state.selectedTime} onChange={this.handleTimeChange} onOpenChange={this.handleOpenChange} format="HH:mm" /> ); } } ``` ### 实现原理 1. **状态固化**:通过`selectedTime`存储已选时间,组件`value`始终绑定该状态[^1]。 2. **打开选择器时重置**:利用`hackValue`在打开选择器时强制显示原时间范围,覆盖用户操作[^2]。 3. **修改拦截**:在`onChange`中通过时间对比判断是否允许修改,仅接受与原值相同的选择(实际不可修改)。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值