12
votes

Routes de correspondance multiples

J'ai une application backbone.js qui définit deux contrôleurs, et les contrôleurs définissent tous les deux des modèles de route correspondant à l'emplacement.Hash. J'ai des difficultés à les tirer des deux pour tirer - par exemple

ManagerController = Backbone.Controller.extend({
   routes: {
      ":name":      "doStuff"
   },

   doStuff : function(name) {
      console.log("doStuff called...");
   }
});

Component1Controller = Backbone.Controller.extend({
   routes: {
      "xyz123":      "doMoreStuff"
   },

   doMoreStuff : function() {
      console.log("doMoreStuff called...");
   }
});


0 commentaires

5 Réponses :


15
votes

Réponse courte: Non, vous ne pouvez pas faire cela. Un contrôleur par page.

Réponse longue: Lorsque vous instaniez un nouveau contrôleur, il ajoute ses itinéraires à l'historique Singleton. L'Historique Singleton surveille le composant Hash de l'URL et lorsque le hachage change, il analyse les itinéraires de la première expression qui correspond à ses besoins. Il tire ensuite la fonction associée à cet itinéraire (cette fonction a été liée au contrôleur dans lequel elle a été déclarée). Il ne tirera que une fois, et s'il y a un conflit, l'ordre dans lequel il incendie est formellement indéterminé. (En pratique, il est probablement déterministe.)

Réponse philosophique: Le contrôleur est un objet "Vue" qui affecte la présentation de la page entière basée sur le composant HASH de l'URL. Son objectif est de fournir des URL capables de marque-forme que l'utilisateur peut atteindre à l'avenir, de sorte que lorsqu'il passe à une URL, il peut commencer par une vue présélectionnée parmi beaucoup. De votre description, on dirait que vous manipulez cet élément adressé publiquement exposé manuellement pour manipuler différentes parties de votre fenêtre, tout en laissant les autres seuls. Ce n'est pas comme ça que ça marche.

Une des bonnes choses à propos de la colonne vertébrale est que si vous passez un itinéraire qui est déjà une expression régulière, il l'utilisera comme. Donc, si vous essayez d'utiliser le contrôleur pour créer une description boditkmable de la disposition (composant 1 dans le coin supérieur droit du mode d'affichage "A", composant 2 dans le coin supérieur gauche du mode d'affichage "B", etc.) Je peux suggérer un certain nombre d'alternatives-- allouer chacun un espace de noms dans la partie de hachage de l'URL et créer des itinéraires qui ignorent le reste, c'est-à-dire xxx

voir comment le premier utilise uniquement des éléments après la première barre oblique, la seconde après la seconde barre oblique, etc. Vous pouvez encoder votre magie entièrement comment vous voulez.

Je suggère, si vous voulez faire quelque chose avec L'aspect et la convivialité des composants, et vous voulez que cela soit raisonnablement persistant, que vous examinez les vues Obtenir et fixer leurs biscuits de certains magasins locaux; S'ils sont assez petits, les cookies suffiront.


4 commentaires

Merci Elf - Dans ce cas, une page comprend arbitrairement des composants de différents développeurs, donc je ne peux donc pas préciser explicitement le contrôleur. Seul 1 composant est visible à la fois, avec les autres dans le DOM, mais caché. Le hachage a des pièces: / / * . Le 1er identifie quel composant à afficher, le reste est destiné au composant. D'après ce que vous dites, je pourrais essayer une approche où chaque composant enregistre un itinéraire et un rappel avec le contrôleur principal, qui fait les itinéraires et le procuration des rappels. Un modèle de contrôleur de délégué personnalisé, je suppose. Ta.


Elfe, quelques corrections. 1) Vous pouvez avoir autant de contrôleurs (maintenant appelés routeurs) que vous le souhaitez sur une page. La colonne vertébrale continuera simplement à préparer les définitions de l'itinéraire dans l'histoire Singleton. 2) L'ordre dans lequel les itinéraires sont vérifiés est la dernière entrée = premier vérifié.


C'est vraiment trop mauvais; Il semble un peu démontré de la part des développeurs de colonne vertébrale, car il y a des raisons parfaitement valables pour que vous souhaitiez avoir plusieurs parties d'une page qui ne doivent pas nécessairement être étroitement liées les unes des autres afin de travailler. Tout le monde ne veut pas "un contrôleur d'une page de les gouverner tous"


Il n'y a rien qui vous empêche d'avoir plusieurs parties de la page qui ne sont pas étroitement liées. Je l'ai fait tout le temps dans la colonne vertébrale. Le routeur ne doit pas nécessairement être le contrôleur de page. Si vous souhaitez une application à une seule page avec des vues individuelles en bref, vous utilisez le routeur.



7
votes

J'ai un problème très similaire. À l'heure actuelle, la colonne vertébrale s'arrête après la première route correspondante. J'ai une solution de contournement sale où je remplace la méthode Loadurl de l'histoire de la colonne vertébrale. Ici, je suis itération via tous les itinéraires enregistrés et déclenchent le rappel pour toutes les voies correspondantes.

_.extend(Backbone.History.prototype, {
  loadUrl : function() {
    var fragment = this.fragment = this.getFragment();
    var matched = false;
    _.each(this.handlers, function(handler) {
      if (handler.route.test(fragment)) {
        handler.callback(fragment);
        matched = true;
      }
    });
    return matched;
  }
})


0 commentaires

1
votes

J'ai utilisé les noms de noms pour faire face à un problème similaire. Chaque module est livré avec son propre contrôleur de module, mais est limité à la poignée des itinéraires qui commencent par / modulename / de cette façon, peuvent être développés indépendamment.


0 commentaires

0
votes

Je n'ai pas encore testé cela à ce moment-là, si vous jetez un coup d'œil à la source de sackbone.js, vous pouvez le voir à la ligne 1449:

// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl: function(fragment) {
  fragment = this.fragment = this.getFragment(fragment);
  return _.any(this.handlers, function(handler) {
    if (handler.route.test(fragment)) {
      handler.callback(fragment);
      return true;
    }
  });
}


0 commentaires

0
votes

Je pense que c'est le moyen le plus simple de résoudre celui-ci

itinéraires: { '': 'usergrid', 'Utilisateurs': 'usergrid', }


0 commentaires