7

我正在为日期时间对象使用自定义 angular.js 过滤器:

function relativeTimeFilter()
{
    return function (dateObj) {
        return getRelativeDateTimeString(dateObj);
    };
}

function getRelativeDateTimeString(dt)
{
    if(!dt) return "undefined ago";

    var delta = dt.getSeconds();
    if (delta < 0) return "not yet";
    if (delta < 1 * 60) return delta == 1 ? "one second ago" : delta + " seconds ago";
    if (delta < 2 * 60) return "a minute ago";
    if (delta < 45 * 60) return Math.floor(delta/60) + " minutes ago";
    if (delta < 90 * 60) return "an hour ago";
    if (delta < 24 * (60*60)) return Math.floor(delta/60/60) + " hours ago";
    if (delta < 48 * (60*60)) return "yesterday";
    if (delta < 30 * (24 * (60*60))) return Math.floor(delta/60/60/24) + " days ago";
    if (delta < 12 * (30 * (24 * (60*60))))
    {
        var months = Math.floor(delta/60/60/24/30);
        return (months <= 1) ? "one month ago" : (months + " months ago");
    }
    else
    {
        var years = Math.floor(delta/60/60/24/365);
        return (years <= 1) ? "one year ago" : (years + " years ago");
    }
}

module.filter("relativetime", relativeTimeFilter);

在这一点上,我使用哪个过滤器并不那么重要(我认为)。过滤器接收一个 Datetime 对象。相对时间声明仅有效一秒。含义one second ago必须在一秒钟后更新2 seconds ago,以此类推。

当我应用过滤器时,这只发生一次。那么如何定期触发过滤器设备呢?

我尝试了以下方法:

setInterval(function() {$scope.$apply()}, 1000) // placed in controller function

...没有成功。

有任何想法吗?

4

2 回答 2

7

我认为您无法通过过滤器实现此目的。$scope.$apply()不起作用的原因是因为它正在监视数据的变化。由于数据实际上并没有改变,所以过滤器再也不会被调用。

相反,您需要调整控制器中正在查看的数据。使用$timeout而不是setInterval因为它内置在消化生命周期中。

我会考虑使用指令来做到这一点。

app.directive('relativeTime', function($timeout) {

  function update(scope, element) {
    element.text(getRelativeDateTimeString(scope.actualTime));
    $timeout(function() { update(scope, element); }, 1000);
  }

  return {
    scope: {
      actualTime: '=relativeTime'
    },
    link: function(scope, element) {
      update(scope, element);
    }
  };
});

所以你可以像这样使用指令:

<div relative-time="theDate"></div>

另外,我发现您的getRelativeDateTimeString功能存在缺陷。您需要将您的增量基于当前时间。 getSeconds只是给你给定时间的秒数:

var delta = parseInt(((new Date().getTime()) - dt.getTime()) / 1000);

这是一个有效的CodePen

于 2013-09-02T09:50:07.923 回答
2

下面是工作 jsfiddle 使用指令来更新时间,我想你正在寻找类似的代码..

http://jsfiddle.net/vishalvasani/xRg3j/

它用

$timeout
于 2013-09-02T10:06:49.147 回答