2013-06-27 11 views
13

Ich bin Migrieren einer einseitigen Webanwendung basierend auf Backbone.js und jQuery auf eine Chrome-Erweiterung. Jedoch scheinen weder die pushState noch die Hashbang-basierten Router-Modi gut mit der Umgebung innerhalb der Erweiterung zu spielen. Ich bin zu dem Schluss gekommen, dass es mir besser geht, Ansichten von Benutzerinteraktionen direkt zu rendern, indem ich das System window.location komplett umgehe. Allerdings bin ich mir nicht sicher, wie dies implementiert werden soll, ohne die Aufrufe an Router.navigate in Dutzenden von Dateien zu ändern.Backbone.js Routing ohne Änderung der URL

Gibt es eine steckbare/modulare Möglichkeit, das Backbone-Routing-System beizubehalten, aber alle Änderungen an der URL zu umgehen?

Antwort

22

ich Sie wirklich mit der Verwendung von Router.navigate haften mögen aus dem Routing profitieren System, das Backbone.js bietet, ohne mit Hashbang-Bugs umgehen zu müssen, wenn es in einer Chrome-Erweiterung verwendet wird (z. B. Routen mit einem Schrägstrich, der überschrieben wird), könnten Sie Router.navigate direkt die URL laden, überspringen die gesamte gymnastische PushState.

Dies ist eigentlich recht einfach zu bewerkstelligen:

Router = Backbone.Router.extend({ 

    navigate: function (url) { 

    // Override pushstate and load url directly 
    Backbone.history.loadUrl(url); 

    }, 

    // Put routes here 
    routes: { } 

}); 

Sie dann Router.navigate(url) nennen können eine neue Route laden Geschichte ohne Änderung oder sogar die Aktion zu jeder Verbindung binden enthält, mit einem data-backbone Attribute (zB <a href="login" data-backbone>Login</a>) ein Ereignis wie folgt:

$(function(){ 

    // Initialize router 
    Router = new Router; 
    Backbone.history.start(); 

    // Bind a[data-backbone] to router 
    $(document).on('click', 'a[data-backbone]', function(e){ 
    e.preventDefault(); 

    Router.navigate($(this).attr('href')); 
    }); 

}); 
2

Sie könnten neu definieren, was Router.navigate tut, aber Sie sind besser dran, nur nicht mit dem Background.router insgesamt. Ich denke, es könnte Verwirrung stiften, und Ihr Code wird sauberer ohne ihn sein, wenn Sie gerade Änderungen aus den Ansichten auslösen.

Backbone.Marionette hat ein Konzept von Controllern, die viel wie Router ohne eine URL-Karte arbeiten (mit Marionette, ist die Idee, Ihre Route Definitionen minimal zu halten, und Anruf-Controller für das Verhalten stattdessen). Sie müssen auch keine Komponenten von Marionette verwenden, die Sie nicht wollen.

Wenn Sie wirklich mit dem Router halten wollten, wie es ist, könnten Sie wahrscheinlich neu definieren nur Backbone.History.navigate zu (beachten Sie, ungetestet)

navigate: function(fragment, options) { 
    if (!History.started) return false; 
    if (!options || options === true) options = {trigger: options}; 
    fragment = this.getFragment(fragment || ''); 
    if (this.fragment === fragment) return; 
    this.fragment = fragment;  
    if (options.trigger) this.loadUrl(fragment); 
} 
+1

AppRouter ist, was anstelle von Router verwendet werden sollte. Die Marionette Controller-Klasse ist nun veraltet - jedes Objekt kann als Controller für die Verwendung durch einen AppRouter dienen. – Paul