在Angularjs和Momentjs中更新"time ago"值

Cor*_*wis 11 angularjs momentjs

原文:我有一个用ng-repeat生成的表,有数百个条目,包含几个不同的unix时间戳.我正在使用moment.js让它们显示为"19分钟前",或者很久以前就是这样.例如,我怎么能每五分钟更新一次这些更新,而不必刷新整个表格(这需要几秒钟,并会中断用户的排序和选择).

Vei*_*kko 17

我使用以下过滤器.每60秒过滤一次更新值.

angular
  .module('myApp')
  .filter('timeAgo', ['$interval', function ($interval){
    // trigger digest every 60 seconds
    $interval(function (){}, 60000);

    function fromNowFilter(time){
      return moment(time).fromNow();
    }

    fromNowFilter.$stateful = true;
    return fromNowFilter;
  }]);
Run Code Online (Sandbox Code Playgroud)

并在HTML中

<span>{{ myObject.created | timeAgo }}</span>
Run Code Online (Sandbox Code Playgroud)


Mar*_*cok 13

我相信每个摘要周期都会对过滤器进行评估,因此使用过滤器显示"time ago"字符串可能会因数百个条目而变得昂贵.

我决定采用pubsub体系结构,主要使用eburley建议的方法(主要是因为我不必监视$destroy事件并手动取消订阅),但使用NotificationService而不是"Channel"函数:

.factory('NotificationService', ['$rootScope',
function($rootScope) {
    // events:
    var TIME_AGO_TICK = "e:timeAgo";
    var timeAgoTick = function() {
        $rootScope.$broadcast(TIME_AGO_TICK);
    }
    // every minute, publish/$broadcast a TIME_AGO_TICK event
    setInterval(function() {
       timeAgoTick();
       $rootScope.$apply();
    }, 1000 * 60);
    return {
        // publish
        timeAgoTick: timeAgoTick,
        // subscribe
        onTimeAgo: function($scope, handler) {
            $scope.$on(TIME_AGO_TICK, function() {
                handler();
            });
        }
    };
}])
Run Code Online (Sandbox Code Playgroud)

time-ago指令寄存器/预订时间戳(post.dt在下面的示例HTML)与NotificationService:

<span time-ago="post.dt" class="time-ago"></span>
Run Code Online (Sandbox Code Playgroud)

.directive('timeAgo', ['NotificationService',
function(NotificationService) {
    return {
        template: '<span>{{timeAgo}}</span>',
        replace: true,
        link: function(scope, element, attrs) {
            var updateTime = function() {
                scope.timeAgo = moment(scope.$eval(attrs.timeAgo)).fromNow();
            }
            NotificationService.onTimeAgo(scope, updateTime); // subscribe
            updateTime();
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)

一些评论:

  • 我试图提高效率,而不是让指令创建一个新的范围.虽然该指令timeAgo在范围中添加了一个属性,但在我的用法中,这是可以的,因为我似乎只time-ago在ng-repeat中使用该指令,所以我只是将该属性添加到由ng-repeat创建的子范围.
  • {{timeAgo}} 将在每个摘要周期检查,但这应该比运行过滤器更快
  • 我也喜欢这种方法,因为我没有在每个时间戳上运行的计时器.我在NotificationService中运行了一个计时器.
  • 函数timeAgoTick()可以是私有的,因为可能只有NotificationService需要发布time time事件.


jan*_*sen 4

使用 Angular 的$timeout服务(只是一个包装器setTimeout())来更新您的数据。请注意第三个参数,它指示 Angular 应该运行一个$digest循环来更新您的数据绑定。

这是一个示例: http://jsfiddle.net/jandersen/vfpDR/
(此示例每秒更新一次,因此您不必等待 5 分钟即可看到它;-)