140 votes

Backbone.js: en cours de route

À l'aide de la Dorsale, est-il possible pour moi d'obtenir le nom de l'itinéraire actuel? Je sais comment lier la route à modifier les événements, mais je voudrais être en mesure de déterminer la voie à d'autres moments, entre les changements.

212voto

Robert Points 4974

Si vous avez instancié un Routeur dans votre application, la ligne suivante renvoie le fragment:

Backbone.history.fragment;

À partir de la Backbone.js documentation:

" [...] L'histoire sert un mondial du routeur (par image) pour gérer hashchange des événements ou des pushState, correspondent à la voie appropriée, et de déclencher des rappels. Vous ne devriez jamais avoir à en créer un de ces vous-même - vous devez utiliser la référence à la colonne vertébrale.l'histoire qui sera créé automatiquement pour vous si vous utilisez des Routeurs avec les routes. [...]"

Si vous avez besoin du nom de la fonction liée à ce fragment, vous pouvez faire quelque chose comme ceci à l'intérieur de la portée de votre Routeur:

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

Ou comme ce à partir de l'extérieur de votre routeur:

alert( myRouter.routes[Backbone.history.fragment] );

57voto

Simon Kjellberg Points 515

Robert réponse est intéressante, mais malheureusement il ne fonctionne que si le hachage est exactement comme défini dans la route. Par exemple si vous avez un itinéraire pour user(/:uid) il ne sera pas égalé si l' Backbone.history.fragment est soit "user" ou "user/1" (les deux sont les deux exemples les plus évidents des cas d'utilisation d'un tel itinéraire). En d'autres termes, il ne fera que trouver le bon nom de rappel si le hachage est exactement "user(/:uid)" (très peu probable).

Depuis que j'ai besoin de cette fonctionnalité, j'ai étendu l' Backbone.Router avec un current-fonction qui réutilise le code de l'Histoire et de Routeur objet l'utilisation selon l'état de fragment contre les trajets définis pour déclencher le rappel approprié. Pour mon cas d'utilisation, il prend le paramètre facultatif route, si elle est définie à quoi que ce soit véridique sera de retour de la fonction correspondante nom défini pour la route. Sinon ça va retourne le hash-fragment d' Backbone.History.fragment.

Vous pouvez ajouter le code à votre mesure où l'initialisation et de configuration du routeur de la colonne vertébrale.

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'

Je suis sûr que certaines améliorations pourraient être apportées, mais c'est un bon moyen pour obtenir vous avez commencé. Aussi, il est facile de créer cette fonctionnalité sans sortir de la Route-objet. Je l'ai fait parce que c'était le moyen le plus pratique pour mon set-up.

Je n'ai pas testé encore, de sorte s'il vous plaît laissez-moi savoir si quelque chose va vers le sud.


Mise à JOUR 04/25

J'ai fait quelques changements à la fonction, de sorte qu'au lieu de retourner le hachage ou de voie nom de rappel, je retourne un objet avec fragment, params et de la route de sorte que vous pouvez accéder à toutes les données de l'itinéraire actuel, un peu comme vous le feriez à partir de la route de l'événement.

Vous pouvez voir les changements ci-dessous:

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

Voir le code précédent pour plus de commentaires et d'explications, ils regardent essentiellement les mêmes.

11voto

yoshisurfs Points 511

Pour obtenir de l'appel de la route (ou url) de l'appelé gestionnaire d'itinéraire, vous pouvez l'obtenir par la vérification de l'

De la colonne vertébrale.l'histoire.emplacement.href ... l'url complète
De la colonne vertébrale.l'histoire.emplacement.recherche ... de chaîne de requête à partir de ?

Je suis ici à la recherche de cette réponse, donc je suppose que je devrais quitter ce que j'ai trouvé.

6voto

user1310662 Points 73

Si vous utilisez la racine de réglage pour le Routeur, vous pouvez également inclure d'obtenir la "vraie" fragment.

(Backbone.history.options.root || "") + "/" + Backbone.history.fragment

6voto

Dan Points 16670

Voici un peu plus de commentaires (ou, selon votre goût, plus lisible) de la version de Simon réponse:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X