原文:我有一个用ng-repeat生成的表,有数百个条目,包含几个不同的unix时间戳。我正在使用moment.js让它们显示为“19分钟前”,或者很久以前就是这样。我如何每五分钟更新一次,例如,无需刷新整个表格(这需要几秒钟,并会中断用户的排序和选择)。
答案 0 :(得分:16)
我使用以下过滤器。每60秒过滤一次更新值。
var text = g.append("text")
.style("font-size", 20)
.append("textPath")
.text(function(d, i) {
return segments[i];
})
.attr("textLength", function(d, i) {
return 90 - i * 5;
})
.attr("xlink:href", function(d, i) {
return "#s" + i;
})
.attr("startOffset", function(d, i) {
return segmentOffsets[i];
})
并在html中
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;
}]);
答案 1 :(得分:13)
我相信filters are evaluated every digest cycle,所以使用过滤器显示你的"之前的时间"数百个条目可能会使字符串变得昂贵。
我决定使用pubsub架构,使用基本上eburley's建议的方法(主要是因为我不必注意$destroy
事件并手动取消订阅),但使用NotificationService而不是而不是"频道"功能:
.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();
});
}
};
}])
time-ago
指令使用NotificationService注册/订阅时间戳(下面的示例HTML中为post.dt
):
<span time-ago="post.dt" class="time-ago"></span>
.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();
}
}
}])
一些评论:
timeAgo
属性,但在我的使用中,这是可以的,因为我似乎只在ng-repeat中使用time-ago
指令,所以我只是添加由ng-repeat创建的子范围的属性。{{timeAgo}}
,但这应该比运行过滤器更快timeAgoTick()
可以设为私有,因为可能只有NotificationService需要发布time time事件。答案 2 :(得分:4)
使用angular的$timeout
服务(只是setTimeout()
周围的包装)来更新您的数据。请注意第三个参数,它指示Angular应运行$digest
周期,以更新数据绑定。
以下是一个例子:http://jsfiddle.net/jandersen/vfpDR/
(此示例每秒更新一次,因此您不必等待5分钟才能看到它; - )
答案 3 :(得分:0)
我最后通过setInterval每隔五分钟调用一次scope.apply(),它会重新应用将时间戳格式化为“x分钟前”的过滤器。也许有点hacky但它的确有效。我确定这不是最佳解决方案。
答案 4 :(得分:0)
我为momentjs https://github.com/jcamelis/angular-moment
制作了一个包装器<p moment-interval="5000">{{"2014-05-21T14:25:00Z" | momentFromNow}}</p>
我希望它适合你。