web-dev-qa-db-fra.com

Pourquoi est-il considéré comme une mauvaise pratique d'appeler trigger: true dans la fonction de navigation de backbone.js?

J'ai lu à plusieurs endroits que l'appel de la fonction Backbone.history.navigate est considéré comme une mauvaise pratique.

Par exemple, Addy Osmani a écrit dans son livre "Developing Backbone.js Applications"

Il est également possible que Router.navigate () déclenche la route le long de avec la mise à jour du fragment d'URL en passant le déclencheur: true option . Note: Cette utilisation est déconseillée ...

http://addyosmani.github.io/backbone-fundamentals/#backbone.history

Ou Derick Bailey dans son blog post même sais:

La plupart du temps, vous ne devez pas exécuter le gestionnaire de route à partir de votre application.

Mais je ne comprends pas vraiment le raisonnement derrière cela et quelle serait une meilleure solution.

À mon avis, il n’est pas vraiment mauvais d’appeler la fonction de navigation avec le déclencheur: vraie option. Lors de l'appel, la fonction de route peut toujours vérifier si les données considérées sont déjà chargées et afficher ces données chargées au lieu de tout refaire à nouveau ...

32
DanEEStar

Je ne suis pas d'accord avec la réponse de @ Stephen ici. Et la raison principale en est que l'utilisation de router.navigate({trigger : true}) donne au routeur la responsabilité de gérer l'état de l'application. Il ne devrait contenir que refléter état de l'application, pas le contrôler.

De plus, il n’est pas de la responsabilité de View de changer le hachage de la fenêtre, c’est le travail du routeur {seulement! Ne l'enlève pas! Une bonne modularité et une séparation des problèmes permettent une application évolutive et facile à gérer.

Transférer une personne vers une nouvelle section de votre application

Le backbone est un framework event driven, utilise des événements pour communiquer. Il n'est absolument pas nécessaire d'appeler router.navigate({ trigger : true }) car les fonctionnalités ne doivent pas figurer dans le routeur. Voici un exemple de la manière dont j'utilise le routeur et qui, à mon avis, favorise une bonne modularité et une séparation des problèmes.

var Router = Backbone.Router.extend({
  initialize: function(app) {
    this.app = app;
  },
  routes: {
    'videoLibrary' : function() { this.app.videoLibrary(); }
  }
});

var Application = _.extend({}, Backbone.Events, {
  initialize: function() {
    this.router = new Router( this );
    this.listenTo( Backbone, 'video:uploaded', function() { 
      this.router.navigate('/videoLibrary');
      this.videoLibrary();
    });
  },
  videoLibrary: function() {
    //do useful stuff
  }
});

var uploadView = Backbone.View.extend({
  //...
  uploadVideo: function() {
    $.ajax({
      //...
      success: function() { Backbone.trigger('video:uploaded'); }
    });
  }
});

Votre point de vue n'a pas besoin ou envie de savoir quoi faire lorsque l'utilisateur a terminé le téléchargement, cette responsabilité incombe à quelqu'un d'autre. Dans cet exemple, le routeur n'est qu'un point d'entrée pour la fonctionnalité de l'application, un événement généré par uploadView en est un autre. Le routeur reflète toujours l'état de l'application par le biais des modifications de hachage et de l'historique, mais n'implémente aucune fonctionnalité.

Testabilité

En séparant les préoccupations, vous améliorez la testabilité de votre application. Il est facile d'avoir un espion sur Backbone.trigger et de s'assurer que la vue fonctionne correctement. Il est moins facile de se moquer d'un routeur.

Gestion des modules

De plus, si vous utilisez une gestion de module telle qu'AMD ou CommonJS, vous devrez passer l'instance du routeur partout dans l'application pour pouvoir l'appeler. Ainsi, avoir un couplage étroit dans votre application ne correspond pas à vos souhaits.

11
mor

À mon avis, c'est considéré comme une mauvaise pratique, car vous devriez imaginer une application Backbone non pas comme une application Ruby on Rails mais plutôt comme une application de bureau.

Lorsque je dis RoR, je dis simplement un framework prenant en charge le routage dans le sens où une route vous amène à un appel spécifique au contrôleur pour exécuter une action spécifique (imaginez une opération CRUD).

Backbone.history est uniquement conçu comme un signet pour permettre à l'utilisateur, par exemple, de sauvegarder une URL spécifique et de l'exécuter à nouveau ultérieurement. Dans ce cas, il trouvera la même situation qu'il a laissée auparavant.

Quand tu dis:

À mon avis, il n’est pas vraiment mauvais d’appeler la fonction de navigation avec le déclencheur: vraie option. La fonction route peut toujours être appelée en appelant Vérifiez si les données considérées sont déjà chargées et montrez-les .__ chargé. données au lieu de refaire tout le travail ...

Cela me semble odorant. Si vous déclenchez un itinéraire et que vous vérifiez les données pour voir si vous les avez, cela signifie que vous les aviez déjà; vous devez donc modifier votre vue en conséquence sans charger à nouveau le DOM entier avec les mêmes données.

Ceci dit trigger:true y at-il donc une raison pour l’utiliser? À mon avis, il est possible de l'utiliser si vous échangez complètement une vue.

Disons que j'ai une application avec deux onglets, l'un me permet de créer une seule ressource, l'autre me permet de voir la liste des ressources créées. Dans les deuxièmes onglets, vous chargez réellement une collection, de sorte que les données sont différentes entre les deux. Dans ce cas, j'utiliserais trigger:true.

Cela dit, cela fait 2 semaines que j'utilise Backbone, je suis donc relativement novice dans ce monde, mais il me semble raisonnable de décourager l'utilisation de cette option.

3
dierre

Cela dépend de votre contexte. 

Si, dans votre vue actuelle, vous avez effectué une action susceptible d’affecter celle à laquelle vous allez accéder, par exemple créer pour supprimer un enregistrement client, il est judicieux de définir trigger sur true.

Penses-y. Si vous supprimez un enregistrement client, ne souhaitez-vous pas actualiser la liste des clients pour refléter cette suppression? 

1
l3x