webentwicklung-frage-antwort-db.com.de

Warum wird der Aufruf von trigger: true in der Navigationsfunktion von backbone.js als schlechte Praxis betrachtet?

Ich habe an mehreren Stellen gelesen, dass das Aufrufen der Backbone.history.navigate-Funktion als schlechte Praxis gilt.

Zum Beispiel sagt Addy Osmani in seinem Buch "Developing Backbone.js Applications"

Es ist auch möglich, dass Router.navigate () die Route entlang von .__ auslöst. mit dem Aktualisieren des URL-Fragments durch Übergeben der Option trigger: true . Hinweis: Von dieser Verwendung wird abgeraten ...

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

Oder Derick Bailey in seinem blog post sogar sais:

Sie sollten den Handler der Route meistens nicht innerhalb Ihrer Anwendung ausführen.

Aber ich verstehe nicht wirklich die Gründe dahinter und was wäre eine bessere Lösung.

Meiner Meinung nach ist es nicht schlimm, die Navigate-Funktion mit der Option trigger: true aufzurufen. Die route-Funktion konnte beim Aufruf immer überprüfen, ob die betrachteten Daten bereits geladen sind, und diese geladenen Daten anzeigen, anstatt die gesamte Arbeit erneut zu erledigen ...

32
DanEEStar

Es scheint einige Verwirrung darüber zu geben, was Router#navigate genau tut, denke ich.

Ohne festgelegte Optionen wird die URL des angegebenen Fragments aktualisiert. Z.B. router.navigate('todo/4/edit') wird die URL aktualisieren zu #todo/4 UND wird einen Browserverlaufseintrag erstellen für diese URL. Es werden keine Routenhandler ausgeführt.

Wenn Sie jedoch trigger:true einstellen, wird die URL aktualisiert, aber es wird auch der Handler ausgeführt, der für diese Route angegeben wurde (im Addy-Beispiel werden die Router editTodo und aufgerufen) Erstellen Sie einen Browserverlaufseintrag.

Bei der Übergabe von replace:true wird die URL aktualisiert, es wird kein Handler aufgerufen, aber es wird KEIN Eintrag im Browserverlauf erstellt.

Was ich denke, ist die Antwort:

der Grund, warum von der Verwendung von trigger:true abgeraten wird, ist einfach. Das Navigieren von Anwendungsstatus zu Anwendungsstatus erfordert meistens, dass ein anderer Code ausgeführt wird als beim direkten Navigieren zu einem bestimmten Anwendungsstatus.

Nehmen wir an, Sie haben die Zustände A, B und C in Ihrer Anwendung. Zustand B baut jedoch auf Zustand A und Zustand C auf B auf. In diesem Fall muss beim Navigieren von B nach C nur ein bestimmter Teil des Codes ausgeführt werden, während beim direkten Treffen von Zustand C wahrscheinlich eine Statusprüfung und -vorbereitung durchgeführt wird :

  • wurden diese Daten geladen? Wenn nicht, laden Sie es.
  • ist der Benutzer angemeldet? Wenn nicht, leiten Sie weiter.

usw.

Nehmen wir ein Beispiel: Status A (#list) zeigt eine Liste von Songs. In Status B (#login) geht es um die Benutzerauthentifizierung, und in Status C (#list/edit) kann die Liste der Titel bearbeitet werden.

Wenn der Benutzer den Status A erreicht, wird die Liste der Titel geladen und in einer Sammlung gespeichert. Er klickt auf einen Login-Button und wird zu einem Login-Formular weitergeleitet. Er authentifiziert sich erfolgreich und wird zurück zur Songliste geleitet, diesmal jedoch mit Löschtasten neben den Songs.

Er markiert den letzten Status (#list/edit).

Was muss nun geschehen, wenn der Benutzer einige Tage später auf das Lesezeichen klickt? Die Anwendung muss die Songs laden, sicherstellen, dass der Benutzer (noch) angemeldet ist, und entsprechend reagieren, was im Statusübergangsfluss bereits in den anderen Status ausgeführt wurde.

Nun zu meiner eigenen Notiz:

Ich würde den obigen Ansatz in einer realen Anwendung niemals wie im Beispiel empfehlen. Sie sollten prüfen, ob die Sammlung geladen ist, wenn Sie von B nach C wechseln, und nicht einfach davon ausgehen, dass dies bereits der Fall ist. Ebenso sollten Sie prüfen, ob der Benutzer wirklich eingeloggt ist. Dies ist nur ein Beispiel.

IMO ist der Router wirklich eine besondere Art von Ansicht (denken Sie darüber nach, er zeigt den Anwendungsstatus an und übersetzt Benutzereingaben in Anwendungsstatus/-ereignisse) und sollte immer als solche behandelt werden. Sie sollten niemals Verlassen Sie sich auf den Router, um zwischen den Zuständen zu wechseln, sondern lassen Sie den Router die Zustandsübergänge wiedergeben.

25
Creynders

Ich muss der Antwort von @ Stephen hier nicht zustimmen. Der Hauptgrund dafür ist, dass der Router durch die Verwendung von router.navigate({trigger : true}) die Verantwortung für den Status der Anwendung übernimmt. Es sollte nur reflektieren Anwendungsstatus sein, es nicht steuern.

Außerdem ist es nicht die Verantwortung eines View, den Hash des Fensters zu ändern. Dies ist der nur-Job des Routers! Nimm es nicht weg! Eine gute Modularität und Trennung der Anliegen führt zu einer skalierbaren und wartbaren Anwendung.

Weiterleiten einer Person an einen neuen Abschnitt in Ihrer Anwendung

Backbone ist ein ereignisgesteuertes Framework, verwenden Sie Ereignisse zur Kommunikation. Es ist absolut nicht nötig, router.navigate({ trigger : true }) aufzurufen, da die Funktionalität nicht im Router sein sollte. Hier ist ein Beispiel, wie ich den Router benutze, und ich denke, dass eine gute Modularität und die Trennung von Anliegen gefördert werden.

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'); }
    });
  }
});

Ihre Ansicht muss nicht müssen oder möchten wissen, was zu tun ist, wenn der Benutzer mit dem Hochladen fertig ist. Dies liegt in der Verantwortung einer anderen Person. In diesem Beispiel ist der Router nur ein Einstiegspunkt für die Funktionalität der Anwendung. Ein von uploadView generiertes Ereignis ist ein anderes. Der Router spiegelt den Anwendungsstatus immer durch Hash-Änderungen und den Verlauf wider, implementiert jedoch keine Funktionalität.

Testbarkeit

Durch die Trennung der Bedenken verbessern Sie die Testbarkeit Ihrer Anwendung. Es ist einfach, einen Spion auf Backbone.trigger zu haben und sicherzustellen, dass die Ansicht ordnungsgemäß funktioniert. Es ist weniger leicht, einen Router zu verspotten.

Modulverwaltung

Wenn Sie eine Modulverwaltung wie AMD oder CommonJS verwenden, müssen Sie die Instanz des Routers überall in der Anwendung umleiten, um sie aufzurufen. Da Sie in Ihrer Anwendung eine enge Kopplung haben, möchten Sie dies nicht.

11
mor

Meines Erachtens gilt dies als schlechte Praxis, da Sie sich eine Backbone-Anwendung nicht wie eine Ruby on Rails-Anwendung, sondern eine Desktop-Anwendung vorstellen sollten.

Wenn ich RoR sage, sage ich nur ein Framework, das Routing unterstützt, in dem Sinne, dass eine Route Sie zu einem bestimmten Anruf an den Controller führt, um eine bestimmte Aktion auszuführen (stellen Sie sich eine CRUD-Operation vor).

Backbone.history ist nur als Lesezeichen für den Benutzer gedacht, sodass er beispielsweise eine bestimmte URL speichern und später erneut ausführen kann. In diesem Fall wird er dieselbe Situation finden, die er zuvor verlassen hat.

Wenn du sagst:

Meiner Meinung nach ist es nicht schlimm, die Navigationsfunktion mit .__ aufzurufen. die Option trigger: true. Die route-Funktion könnte beim Aufruf immer Prüfen Sie, ob die betrachteten Daten bereits geladen sind, und zeigen Sie diese geladen an Daten, anstatt die ganze Arbeit noch einmal zu machen ...

Das klingt für mich stinkend. Wenn Sie eine Route auslösen und nach den Daten suchen, um zu sehen, ob Sie sie haben, bedeutet dies, dass Sie sie bereits hatten, und Sie sollten Ihre Ansicht entsprechend ändern, ohne das gesamte DOM mit denselben Daten erneut zu laden.

Das besagte trigger:true gibt es also einen Grund, es zu benutzen? Meiner Meinung nach ist es möglich, es zu verwenden, wenn Sie die Ansicht vollständig wechseln.

Nehmen wir an, ich habe eine Anwendung mit zwei Registerkarten. Mit der einen kann ich eine einzige Ressource erstellen, mit der anderen die Liste der erstellten Ressourcen. In den zweiten Registerkarten laden Sie tatsächlich eine Collection, sodass sich die Daten zwischen den beiden unterscheiden. In diesem Fall würde ich trigger:true verwenden.

Das heißt, ich habe Backbone seit 2 Wochen im Einsatz, also bin ich auf dieser Welt ziemlich neu, aber es erscheint mir vernünftig, von dieser Option abzuraten.

3
dierre

Das hängt von deinem Kontext ab. 

Wenn Sie in Ihrer aktuellen Ansicht etwas unternommen haben, das möglicherweise Auswirkungen auf die Ansicht hat, zu der Sie navigieren möchten, z. B. zum Erstellen eines Kundendatensatzes, dann ist es richtig, den Trigger auf true zu setzen.

Denk darüber nach. Wenn Sie einen Kundendatensatz löschen, möchten Sie die Liste der Kunden nicht aktualisieren, um diese Löschung anzuzeigen. 

1
l3x