【问题标题】:JavaScript Timespan ControlJavaScript 时间跨度控制
【发布时间】:2015-05-08 19:53:20
【问题描述】:

我正在尝试构建时间跨度控件。从本质上讲,它是一个控件,允许用户输入年/月/日/小时来表示某件事花费了多长时间。

如果您曾经使用过 JIRA,我认为他们对此有很好的实现。

如果其他人有类似的案例以及您如何通过控件处理它,我会很感兴趣。另外,你将如何处理 JavaScript 中的时间跨度(我在想毫秒)。

目标是创建一个允许用户轻松输入时间跨度的控件。 2 个不同的日期/时间控件对于简单地输入 3h 之类的内容非常令人困惑。

【问题讨论】:

  • 什么是目标?从中创建日期时间?问题非常广泛...可能有助于更新您面临的问题
  • @charlietfl 已更新 :)

标签: javascript jquery angularjs datetime


【解决方案1】:

是的,将输入字符串解析为毫秒是个好主意。因此,您可以稍后使用它进行计算。例如然后您可以使用new Date(your-milliseconds) 创建一个日期对象。

您可以为此编写一个指令,例如下面的演示和jsFiddle

它使用范围方法parseTime(time),该方法使用正则表达式来创建输入数组。所以你会在匹配的结果中有一个数字和关键字母。 然后,该字母将用于获取转换为毫秒的时基,该值是计算的乘数。

为了稍后再次显示输入的时间跨度,我创建了一个过滤器以将毫秒转换回“周、天、...”格式。

演示运行良好,但我认为有一点需要改进。如果在数字和字母之间输入空格,它将不起作用。例如3 周 4 天 12 小时

但这可能很容易解决。它应该通过修剪解析方法中的空白来工作。

'use strict';

angular.module('myApp', []).
constant('formatObj', {
    "w": 7 * 24 * 60 * 60 * 1000, // milliseconds
    "d": 24 * 60 * 60 * 1000,
    "h": 60 * 60 * 1000,
    "m": 60 * 1000,
    "s": 1000,
    "ms": 1
})
    .controller('mainCtrl', function ($scope) {})
    .directive('timeSpanInput', function () {
    return {
        template: '<input ng-model="time" ng-change="parseTime(time)" ' +
            'placeholder="enter time..."></input>(e.g. 3w 4d 12h)<p ng-show="timespan">timespan entered {{timespan | dateSpan}}</p>',
        controller: function ($scope, $filter, formatObj) {
            $scope.parseTime = function (timeStr) {
                var pattern = /(\d+)(\w{1,2})/g, // returns 1w, 1, w from 1w string
                    match,
                    timespan = 0;

                while (match = pattern.exec(timeStr)) {
                    console.log(match); // index=1 value 2=format letter w d h s
                    if (match.length == 3 && isNaN(match[2])) {
                        timespan += match[1] * formatObj[match[2]];
                    }
                }
                //console.log(timespan);
                $scope.timespan = timespan;
            };
        }
    };
})
    .filter('dateSpan', function (formatObj) {
    return function (date) {
        // convert milli seconds to weeks days hours minutes seconds string
        if (angular.isUndefined(date)) return; // date not defined yet.

        var dateObj = {},      // created date obj {w: 3, d: 4, h:12}
            dateResult = date, // used to calculated times
            factor = 0,  // math factor millis to weeks, hours, etc.
            result = ''; // formatted result string

        for (var key in formatObj) {
            factor = formatObj[key];
            dateObj[key] = Math.floor(dateResult / factor);
            dateResult -= dateObj[key] * factor;
        }

        // console.log(dateObj);
        // generate output string
        for (var key in dateObj) {
            if (dateObj[key]) {
                result += (dateObj[key] + key + ' ');
            }
        };
        //console.log('res', result);
        return result;
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<div ng-app="myApp" ng-contoller="mainCtrl">
    <time-span-input></time-span-input>
</div>

【讨论】:

  • 很好的例子!我把你的一些代码打磨得更“棱角分明”。查一下gist.github.com/amcdnl/f5f6372e57c3c455f85e
  • 感谢您分享您的代码,您说得对,它更“有棱角”。 $formatters$parsers 对我来说是新的。我已经更新了这个jsFiddle 中的正则表达式。现在它更加健壮:不区分大小写且没有空格问题(3w 或 3w)。
  • 啊,太好了!我们应该在 Github 上发布这个!
  • 是的,那很好。我在您的要点中看到您正在将角度导入要点中。这是用 ES6 编码的方式吗?我以前没见过这个。
  • ES6 模块通过 systemjs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
相关资源
最近更新 更多