Vertebral.js: obtener ruta actual


Usando Backbone, ¿es posible para mí obtener el nombre de la ruta actual? Sé cómo enlazar a eventos de cambio de ruta, pero me gustaría poder determinar la ruta actual en otros momentos, entre cambios.

 132
Author: Drew Dara-Abrams, 2011-09-27

6 answers

Si ha instanciado un router en su aplicación, la siguiente línea devuelve el fragmento actual:

Backbone.history.getFragment();

De la Columna Vertebral .js documentation :

" [...] El historial sirve como un enrutador global (por fotograma) para manejar eventos de hashchange o pushState, hacer coincidir la ruta apropiada y activar devoluciones de llamada. Nunca deberías tener que crear uno de estos tú mismo - deberías usar la referencia a Backbone.historia que será creada para ti automáticamente si hace uso de Routers con rutas. [...]"

Si necesita el nombre de la función vinculada a ese fragmento, puede hacer algo como esto dentro del alcance de su enrutador:

alert( this.routes[Backbone.history.getFragment()] );

O así desde fuera de tu router:

alert( myRouter.routes[Backbone.history.getFragment()] );
 206
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-28 09:57:02

La respuesta de Robert es interesante, pero lamentablemente solo funcionará si el hash es exactamente como se define en la ruta. Si, por ejemplo, tiene una ruta para user(/:uid) no se coincidirá si el Backbone.history.fragment es "user" o "user/1" (ambos son los dos casos de uso más obvios para dicha ruta). En otras palabras, solo encontrará el nombre de devolución de llamada apropiado si el hash es exactamente "user(/:uid)" (muy poco probable).

Como necesitaba esta funcionalidad extendí la Backbone.Router con una current-función que reutiliza parte del código que el objeto Historial y Enrutador usan para hacer coincidir el fragmento actual con las rutas definidas para activar la devolución de llamada adecuada. Para mi caso de uso, toma el parámetro opcional route, que si se establece en algo veraz devolverá el nombre de función correspondiente definido para la ruta. De lo contrario devolverá el fragmento hash actual de Backbone.History.fragment.

Puede agregar el código a su Extensión existente donde inicializa y configura la columna vertebral router.

var Router = new Backbone.Router.extend({

    // Pretty basic stuff
    routes : {
        "home" : "home",
        "user(:/uid)" : "user",
        "test" : "completelyDifferent"
    },

    home : function() {
        // Home route
    },

    user : function(uid) {
        // User route
    },

    // Gets the current route callback function name
    // or current hash fragment
    current : function(route){
        if(route && Backbone.History.started) {
            var Router = this,
                // Get current fragment from Backbone.History
                fragment = Backbone.history.fragment,
                // Get current object of routes and convert to array-pairs
                routes = _.pairs(Router.routes);

            // Loop through array pairs and return
            // array on first truthful match.
            var matched = _.find(routes, function(handler) {
                var route = handler[0];

                // Convert the route to RegExp using the 
                // Backbone Router's internal convert
                // function (if it already isn't a RegExp)
                route = _.isRegExp(route) ? route :  Router._routeToRegExp(route);

                // Test the regexp against the current fragment
                return route.test(fragment);
            });

            // Returns callback name or false if 
            // no matches are found
            return matched ? matched[1] : false;
        } else {
            // Just return current hash fragment in History
            return Backbone.history.fragment
        }
    }
});

// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'

Estoy seguro de que se podrían hacer algunas mejoras, pero esta es una buena manera de comenzar. Además, es fácil crear esta funcionalidad sin extender la Ruta-objeto. Hice esto porque era la forma más conveniente para mi configuración.

No he probado esto completamente todavía, así que por favor hágamelo saber si algo sale mal.


ACTUALIZACIÓN 25/04/2013

Hice algunos cambios en la función, así que en lugar de devolver el hash o la ruta callback name, devuelvo un objeto con fragmento, parámetros y ruta para que pueda acceder a todos los datos de la ruta actual, al igual que lo haría desde el evento route.

Puede ver los cambios a continuación:

current : function() {
    var Router = this,
        fragment = Backbone.history.fragment,
        routes = _.pairs(Router.routes),
        route = null, params = null, matched;

    matched = _.find(routes, function(handler) {
        route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
        return route.test(fragment);
    });

    if(matched) {
        // NEW: Extracts the params using the internal
        // function _extractParameters 
        params = Router._extractParameters(route, fragment);
        route = matched[1];
    }

    return {
        route : route,
        fragment : fragment,
        params : params
    };
}

Vea el código anterior para más comentarios y explicaciones, se ven casi iguales.

 55
Author: Simon Kjellberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:32:23

Para obtener la ruta de llamada (o url) desde el controlador de ruta llamada, puede obtenerla marcando

Backbone.history.location.href  ... the full url
Backbone.history.location.search  ... query string starting from ?

Llegué aquí en la búsqueda de esta respuesta, así que supongo que debo dejar lo que he encontrado.

 9
Author: yoshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-04 06:05:15

Si utiliza la configuración de raíz para el enrutador, también puede incluirla para obtener el fragmento 'real'.

(Backbone.history.options.root || "") + "/" + Backbone.history.fragment
 6
Author: user1310662,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-09 18:07:47

Aquí hay una tad versión más detallada (o, dependiendo de su gusto, más legible) de La respuesta de Simón:

current: function () {
  var fragment = Backbone.history.fragment,
      routes = _.pairs(this.routes),
      route,
      name,
      found;

  found = _.find(routes, function (namedRoute) {
    route = namedRoute[0];
    name = namedRoute[1];

    if (!_.isRegExp(route)) {
      route = this._routeToRegExp(route);
    }

    return route.test(fragment);
  }, this);

  if (found) {
    return {
      name: name,
      params: this._extractParameters(route, fragment),
      fragment: fragment
    };
  }
}
 5
Author: Dan Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:38

Si nos fijamos en la fuente para el Router, verá que cuando el enrutador desencadena el evento diciendo que algo cambia, pasa el nombre con él como "ruta:nombre".

Http://documentcloud.github.com/backbone/docs/backbone.html#section-84

Siempre puede enganchar el evento "route" en el enrutador y almacenarlo para obtener la ruta actual.

 4
Author: Brian Genisio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-27 11:07:07