前端封装时间选择器时的数据格式问题(JS闭包应用场景)

发布时间 2023-07-13 22:45:46作者: 南丁咯咯哒

工作中遇到一个需求,需要同时支持一定长度时间段与自定义时间段。

时间选择框是一个下拉框,下拉框后面跟两个框分别显示起止时间,默认是禁用状态,下拉框有多个选项,比如一小时,三小时,六小时......最后一项是自定义时间段,选中后起止时间选择框将会解除禁用。

当选中一小时时,每次全新查询都要拿到当前时间基础上的最新时间对,翻页时则不能更新时间,当选中自定义时间时需要传出选中的固定时间对。此时会发现一个问题,当选中时间段时最好传出一个标记或者小时数秒数等,由外部控制时间段的更新操作,但由于自定义时间的存在,组件至少有一个出参是时间对。

以下分析三种最直观的数据格式方案的优劣:

1. 单独传出时间段标记。

此时只能传输固定时间段,当选中自定义时间段是无法提前定义标记,无法实现需求。

2. 单独传出自定义时间对。

此时满足两种时段选项的要求,但又造成了新的问题。选中固定时间段如最近一小时后,如果产生了新的查询,需要更新为当前时间的一小时内,就只有一种方式,也就是显式通知自定义时间选择框更新时间并回传到外部。

这种方式一方面违反了IoC控制反转原则,既不优雅又为未来埋下了隐患,另一方面由于外部需要异步通知子组件更新变量,然后立马接收子组件传过来的变量,很容易造成延迟过高的问题或者同步问题。

3. 同时传出时间段标记和自定义时间对,并根据type参数进行区分。

此时接近完美了,除了需要在外部同时维护时间段和自定义时间对之外,还有一个微小的问题,当新的查询更新时间时,被禁用的时间选择框显式的还是首次选中最近一小时时产生的时间,没办法随着新的查询自动更新。

前端JS有一个很有意思的特性,在函数栈中,由顶层函数产生的子项拥有上层变量的读写权限,也就是所谓的闭包。

根据这种特性可以开发出一种很微妙的数据传输格式----函数。

在时间选择框组件中声明两个变量,用于存储起止时间,同时生成向外部传输的参数。这个参数是一个函数,函数运行时会判断当前选中的时间类型,如果选中了时间段,则生成最新的时间显示在时间选择框并返回,如果选中了自定义时间,则直接返回自定义时间。

当产生新查询时,函数参数本身并不会产生变化,外部通过函数的权限拿到组件内部的选项信息并生成最新时间,同时更新组件视图上显示的时间。