Originale: Ho una tabella generata con ng-repeat con centinaia di voci costituite da diversi timestamp unix diversi. Sto usando moment.js per renderli visualizzati come "19 minuti fa" o comunque molto tempo fa. Come potrei avere questi aggiornamenti ogni cinque minuti, ad esempio, senza dover aggiornare l'intera tabella (che richiede alcuni secondi e interromperà l'ordinamento e le selezioni dell'utente).Aggiornamento dei valori "tempo fa" in Angularjs e Momentjs
risposta
Utilizzare il servizio angolare $timeout
(solo un wrapper attorno a setTimeout()
) per aggiornare i dati. Notare il terzo parametro che indica che Angular deve eseguire un ciclo $digest
che aggiornerà i collegamenti dei dati.
Ecco un esempio: http://jsfiddle.net/jandersen/vfpDR/
(questo esempio viene aggiornato ogni secondo in modo da non dover aspettare 5 minuti per vederlo ;-)
Ho finito per dover $ scope.apply() essere chiamato ogni cinque minuti di setInterval che riapplica i filtri formattando i timestamp in "x minuti fa". Forse un po 'hacky ma funziona. Sono certo che non è la soluzione ottimale.
Credo che filters are evaluated every digest cycle, quindi utilizzando un filtro per visualizzare le stringhe "time fa" potrebbe ottenere CPU costose con centinaia di voci.
ho deciso di andare con un'architettura PubSub, utilizzando essenzialmente eburley's suggerito approccio (soprattutto perché non c'è bisogno di guardare per $destroy
eventi e manualmente cancellare l'iscrizione), ma con un NotificationService piuttosto che una funzione "Canale":
.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();
});
}
};
}])
a time-ago
registri direttiva/sottoscrive un timestamp (post.dt
nell'esempio HTML sottostante) con la 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();
}
}
}])
Alcuni commenti:
- ho cercato di essere efficienti e non hanno la direttiva crea un nuovo ambito. Sebbene la direttiva aggiunga una proprietà
timeAgo
all'ambito, nel mio utilizzo, questo è ok, dal momento che mi sembra di usare solo la direttivatime-ago
all'interno di una ng-repeat, quindi sto solo aggiungendo quella proprietà agli ambiti figlio creati da ng- ripetere. {{timeAgo}}
verrà esaminato ogni ciclo di digest, ma questo dovrebbe essere più veloce di un filtro- Mi piace anche questo approccio perché non ho un timer in esecuzione su ogni timestamp. Ho un timer in esecuzione nel NotificationService.
- La funzione
timeAgoTick()
può essere resa privata, poiché probabilmente solo NotificationService dovrà pubblicare l'evento tempo fa.
Passerò un po 'di tempo a metterlo nella mia implementazione. La mia attuale implementazione non è molto intensa per la CPU rispetto alla mia osservazione, e penso che ci sia un solo timer per l'intera pagina dal momento che quel timer chiama una domanda, ma sono certo che sarebbe meglio. Grazie. –
@CorbinLewis, mi spiace di non essere stato chiaro sui timer multipli ... Stavo pensando a un'implementazione alternativa in cui qualcuno potrebbe usare $ timeout in una direttiva - ciò comporterebbe un timer separato per ogni timestamp. Sono d'accordo che la tua implementazione ha solo un timer. –
Ho fatto un wrapper per momentjs https://github.com/jcamelis/angular-moment
<p moment-interval="5000">{{"2014-05-21T14:25:00Z" | momentFromNow}}</p>
Spero che funziona per voi.
Io uso il seguente filtro. Il filtro aggiorna il valore ogni 60 secondi.
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;
}]);
E in html
<span>{{ myObject.created | timeAgo }}</span>
questo è così bello !!! –
questo è geniale !!! –
- 1. Momentjs Afferra la data odierna e il tempo di impostazione lo fa avanzare rapidamente 24 ore
- 2. Utilizzare jQuery timeago o momentjs e AngularJS insieme
- 3. Aggiornamento dei valori N migliori con PostgreSQL
- 4. In tempo reale con AngularJs e Yii2
- 5. AngularJS ng-options non rendering dei valori
- 6. Valori $ scope in AngularJS
- 7. MomentJS in spagnolo
- 8. Come ottenere una data senza tempo nell'oggetto momentjs esistente?
- 9. MomentJS Day differ date solo escluso il tempo
- 10. Twig - tempo fa formato
- 11. Aggiornamento dei valori di database esistenti dal foglio di calcolo
- 12. Aggiornamento dei valori nel file di file apache
- 13. AngularJS - Passaggio dei valori dal backend al frontend
- 14. Come fare un ticchettio (tempo) in AngularJS e HTML
- 15. php shell_exec con aggiornamento in tempo reale
- 16. Aggiornamento dell'interfaccia utente in tempo reale
- 17. angularjs impostazione dei valori predefiniti da visualizzare prima della valutazione
- 18. Tempo di non aggiornamento in heroku
- 19. proprietà aggiornamento file java tempo di esecuzione
- 20. Aggiornamento dei dati in Clickhouse
- 21. Aggiornamento più valori Mysql
- 22. aggiornamento variabile javascript con ajax in tempo reale
- 23. MomentJS - Destinato alla convalida dell'input?
- 24. AngularJS: costanti vs valori
- 25. AngularJS e uso corretto dei ngCloak
- 26. Come funziona MomentJS confrontando i valori con> e < (and > =, <=)?
- 27. Quali sono i valori di verità e falsi in AngularJS?
- 28. Aggiornamento campi di valori in una ConcurrentDictionary
- 29. Tempo di aggiornamento Android dati della zona
- 30. Aggiornamento del tag del titolo utilizzando AngularJS e UI-Router
vostro collegamento a [ '$ interval'] (https://docs.angularjs.org/api/ng/service/$interval) è corretto, ma il link il testo dice "$ timeout" – jandersen
Nota che angular fornisce anche [$ interval] (https://docs.angularjs.org/api/ng/service/$interval) per le funzioni di chiamata ripetuta. –