web-dev-qa-db-fra.com

SetTimeout vs Ember.run.later dans une application ember?

À l'intérieur de mon modèle de guidon:

Today's date: {{currentDate}}
Current Time: {{currentTime}}

À l'intérieur de mes assistants:

Ember.Handlebars.registerBoundHelper 'currentDate', (option) ->
  moment().format('LL');

Ember.Handlebars.registerBoundHelper 'currentTime', (option) ->
  moment().format('h:mm:ss a');

Comment pourrais-je procéder pour mettre à jour le currentTime à la vue toutes les 1 seconde?

J'ai lu le Ember recommande Ember.run.later mais je ne sais pas trop où le mettre et comment l'appeler en utilisant cette aide.

26
Blair Anderson

Vous pouvez utiliser Ember.run.later comme vous le feriez normalement avec setTimeout

Ember.run.later((function() {
  //do something in here that will run in 2 seconds
}), 2000);

Je ne suis pas sûr des internes, mais je sais que les tests d'intégration Ember nécessite que vous utilisiez run.later (si vous ne le faites pas, le code de test n'attendra pas la fin du délai d'attente) ).

53
Toran Billups

Vous ne voudrez pas ajouter le délai d'attente dans l'assistant, vous voudrez l'ajouter à une variable globale et faire juste une différence à partir d'elle. La raison pour laquelle vous voudrez utiliser Em.run.later c'est qu'il va l'injecter dans la boucle d'exécution (une partie de ce que Toran voulait dire). Ceci est vraiment important pour les tests.

Ajouter l'heure à une variable globale

App.ApplicationRoute = Em.Route.extend({
  setupController: function(controller, model){
    this._super(controller, model);
    this.startWatchingTime(controller);
  },
  startWatchingTime: function(controller){
    var self = this;
    controller.set('currentTime', moment());
    Em.run.later(function(){
      self.startWatchingTime(controller);
    }, 1000);
  }
});

Ajoutez-le à l'aide

Ember.Handlebars.helper('time-diff', function(date1, date2, format, options) {
  return date1.diff(date2, format);
});

l'envoyer dans l'assistant

{{time-diff  controllers.application.currentTime anotherTime 'seconds'}}

http://emberjs.jsbin.com/UcUrIQa/1/edit

12
Kingpin2k

vous souhaitez utiliser la boucle Embers.run au lieu de sortir avec setTimer.

La version actuelle (aujourd'hui) de ember nécessite ce format avec contextthis (mise à jour de la réponse Toran Billups)

this._debouncedItem = Ember.run.later(this, () => {
   debugger;
}, 5000);

Je recommande fortement de conserver une référence à la réponse de later () et de l'annuler dans le crochet destroy

destroy() {
   this._super(...arguments);
   Ember.run.cancel(this._debouncedItem);
},
6
mihai

Vous pouvez faire de currentDate une propriété régulière

currentDate: null,
currentTime: null

Vous pouvez démarrer ce temporisateur dans le constructeur du contrôleur.

init: function () { 
  this.updateTimeProperty();
},
updateTimeProperty: function () {
  var _this = this;
  Ember.run.later(this, function() {
    _this.currentDate = moment().format('LL');
    _this.set('currentTime',  moment().format('h:mm:ss a');
    _this.updateTimeProperty());
  }, 1000);
}
2
Miguel Madero

Je suis un peu dépassé Ember utilisateur, mais je le ferais comme ça en espérant qu'il existe une meilleure solution.

App.CurrentTimeView = Ember.View.extend({
    template : Ember.Handlebars.compile("<span>{{view.currentTime}}</span>"),
    currentTime : null,
    init : function(){
        var view = this;
        view.set('currentTime', moment().format('h:mm:ss a'));
        setInterval((function(view){
            return function(){view.set('currentTime', moment().format('h:mm:ss a'));};
        })(view),1000);
    }
});

et dans le modèle

{{view "App.CurrentTimeView"}}

Pour répondre à votre question, Javascript a une seule exécution filetée (à moins que vous n'utilisiez des webworkers) ce qui signifie qu'il fera les choses une par une de manière sérielle. Lorsque vous utilisez setInterval, il mettra votre fonction en file d'attente toutes les x millisecondes dans cette file d'attente d'exécution principale. setInterval utilise le time passé pour faire sa file d'attente. Ember les boucles d'exécution calculent en quelque sorte les liaisons et autres choses lourdes dans chaque boucle d'exécution, donc à la fin de la boucle, nous sommes sûrs que les changements sont prêts. Il existe des crochets comme Em.run .next pour vous assurer que ces codes lors de l'exécution auront les modifications complètes effectuées dans la dernière boucle d'exécution. De même, lorsque vous passez un temps à Em.run.later, il s'exécutera également après ce temps et prend également en charge un paramètre à définir this à l'intérieur de la fonction. Surtout lorsqu'il s'agit de certaines variables ou données de modèle/contrôleur à l'intérieur de la fonction.

Dans votre cas, setInterval semble ok (pour moi).

http://jsfiddle.net/NQKvy/604/

1
sabithpocker