更新「;“很久以前”;以Angularjs和Momentjs表示的值
原始:我有一个使用ng repeat生成的表,其中有数百个条目,由几个不同的unix时间戳组成。我正在使用moment.js使它们显示为“19分钟前”或是无论它是多久以前。例如,我如何每五分钟更新一次这些数据,而不必刷新整个表(这需要几秒钟的时间,并且会中断用户的排序和选择)。使用angular的服务(仅是更新「;“很久以前”;以Angularjs和Momentjs表示的值,angularjs,momentjs,Angularjs,Momentjs,原始:我有一个使用ng repeat生成的表,其中有数百个条目,由几个不同的unix时间戳组成。我正在使用moment.js使它们显示为“19分钟前”或是无论它是多久以前。例如,我如何每五分钟更新一次这些数据,而不必刷新整个表(这需要几秒钟的时间,并且会中断用户的排序和选择)。使用angular的服务(仅是setTimeout())来更新数据。请注意第三个参数,它指示Angular应该运行更新数据绑定的$digest循环 下面是一个例子: (本例每秒钟更新一次,这样您就不必等待5分钟才能看到它;
setTimeout()
)来更新数据。请注意第三个参数,它指示Angular应该运行更新数据绑定的$digest
循环
下面是一个例子:(本例每秒钟更新一次,这样您就不必等待5分钟才能看到它;-)我最终拥有$scope.apply(),setInterval每五分钟调用一次,它会重新应用过滤器,将时间戳格式化为“x分钟前”。也许有点老套,但很管用。我敢肯定这不是最佳解决方案。我相信,因此使用过滤器显示“时间前”字符串可能会因为数百个条目而导致CPU开销增加 我决定采用pubsub体系结构,使用基本建议的方法(主要是因为我不必监视
$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();
});
}
};
}])
time ago
指令使用NotificationService注册/订阅时间戳(post.dt
,在下面的示例HTML中):
<span time-ago="post.dt" class="time-ago"></span>
.directive('timeAgo',['NotificationService',
功能(通知服务){
返回{
模板:“{timeAgo}}”,
替换:正确,
链接:函数(范围、元素、属性){
var updateTime=function(){
scope.timeAgo=moment(scope.$eval(attrs.timeAgo)).fromNow();
}
NotificationService.onTimeAgo(作用域,更新时间);//订阅
updateTime();
}
}
}])
几点意见:
- 我试图提高效率,而不是让指令创建一个新的范围。尽管该指令向作用域中添加了
属性,但在我的使用中,这是可以的,因为我似乎只在ng repeat中使用timeAgo
指令,所以我只是将该属性添加到ng repeat创建的子作用域中timeAgo
将在每个摘要周期进行检查,但这应该比运行筛选器更快{{timeAgo}}
- 我也喜欢这种方法,因为我没有在每个时间戳上运行计时器。我有一个计时器在NotificationService中运行
- 函数
可以设置为私有,因为可能只有NotificationService需要发布时间间隔事件timeAgoTick()
- 我为momentjs做了一个包装
{{“2014-05-21T14:25:00Z”{momentFromNow}
我希望它对您有用。我使用以下过滤器。过滤器每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;
}]);
和html格式
<span>{{ myObject.created | timeAgo }}</span>
{{myObject.created | timeAgo}
我将花一些时间将其应用到我的实现中。从我的观察来看,我当前的实现并不是CPU密集型的,我认为整个页面只有一个计时器,因为这一个计时器调用应用程序,但我相信这样会更好。谢谢你。@CorbinLewis,对不起,我不清楚多重计时器。。。我正在考虑另一种实现,其中可能有人在指令中使用$timeout——这将导致每个时间戳都有一个单独的计时器。我同意你的实现只有一个计时器。你的链接是正确的,但是链接文本上写着“$timeout”。注意,angular还提供了重复调用函数的功能。
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;
}]);
<span>{{ myObject.created | timeAgo }}</span>