2013-08-01 40 views
11

原文:我有NG-重複數百個由若干不同的UNIX時間戳的條目中產生的表。我使用的是moment.js,讓它們顯示爲「19分鐘前」或不久之前。我怎麼會具有這些更新每隔五分鐘,例如,而不必刷新整個表(這需要幾秒鐘,會打斷用戶的分類和選擇)。更新「很久以前」的Angularjs和Momentjs值

回答

4

使用角度的$timeout服務(只是一個包裝圍繞setTimeout())來更新數據。請注意,表示Angular的第三個參數應運行一個$digest週期,以更新您的數據綁定。

下面是一個例子:http://jsfiddle.net/jandersen/vfpDR/
(這個例子每秒更新,所以你不必等待5分鐘,看看它;-)

+1

你的鏈接['$ interval'(https://docs.angularjs.org/api/ng/service/$interval)是正確的,但鏈接文字說「$超時」 – jandersen

+0

請注意,角度還提供[$間隔](https://docs.angularjs.org/api/ng/service/$interval)用於重複調用函數。 –

0

我最後不得不scope.apply $()被調用每五分鐘由setInterval重新應用格式化時間戳爲「x分鐘前」的過濾器。也許有點hacky,但它的作品。我確定這不是最佳解決方案。

13

我相信filters are evaluated every digest cycle,因此使用過濾器來顯示你的「很久以前」的字符串可能會得到CPU昂貴與數百個條目。

我決定去同一個發佈訂閱架構,採用基本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指令寄存器/預訂時間戳(post.dt在下面的示例HTML)與NotificationService:

<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重複內time-ago指令,所以我只是補充說,物業給孩子用範圍NG-創建重複。
  • {{timeAgo}}將被檢查每個摘要週期,但這應該比運行一個篩選器更快
  • 我也喜歡這種方法,因爲我沒有計時器在每個時間戳上運行。我有一個定時器在NotificationService中運行。
  • 功能timeAgoTick()可以由私人性,因爲可能只有NotificationService將需要發佈的時間以前的事件。
+0

我會花一些時間把它放到我的實現中。我目前的實現並不是我觀察的CPU密集型,我認爲整個頁面只有一個計時器,因爲一個計時器稱爲「應用」,但我確信這會更好。謝謝。 –

+0

@CorbinLewis,對不起,我不清楚多個定時器......我在考慮一個替代實現,其中有人可能會在指令中使用$ timeout - 這會導致每個時間戳都有一個單獨的計時器。我同意你的實現只有一個計時器。 –

14

我使用以下過濾器。每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> 
+0

這太酷了! –

+0

這是輝煌! –