61 votes

Organisation des applications Web volumineuses backbone.js

Je suis actuellement en train de travailler sur une grande application web construit sur backbone.js et y a eu beaucoup de problèmes d'organisation, de "zombies", etc. j'ai donc décidé de faire un grand refactorisation de code. J'ai déjà écrit un tas de fonctions d'assistance pour les relations avec les "zombies"; cependant, je voudrais commencer dès le début et de créer une belle structure/organisation du code. Je n'ai pas trouvé beaucoup de didacticiels et des exemples sur la grande échelle backbone.js organisation donc je avons commencé à partir de zéro et voudrais voir si je peux obtenir quelques avis sur où j'ai commencé.

Je n'ai évidemment mis en place mon code au sein d'un espace de noms global; mais j'aimerais aussi garder de l'espace de nom plutôt propre. Mon principal app.js conserve les fichiers de classe eux-mêmes séparés de l'espace de noms global; vous pouvez vous inscrire à une classe (de sorte qu'il peut être instancié) à l'aide de la reg() et la fonction de l'inst() instancie une classe de classes de tableau. Ainsi, outre les 3 méthodes, la MyApp espace de noms a seulement Routeur, de Modèle et de Vue:

var MyApp = (function () {

    var classes = {
        Routers: {},
        Collections: {},
        Models: {},
        Views: {}
    };

    methods = {

        init: function () {
            MyApp.Router = MyApp.inst('Routers', 'App');
            MyApp.Model = MyApp.inst('Models', 'App');
            MyApp.View = MyApp.inst('Views', 'App');
            Backbone.history.start();
        },

        reg: function (type, name, C) {
            classes[type][name] = C;
        },

        inst: function (type, C, attrs) {
            return new classes[type][C](attrs || {});
        }

    };

    return methods;

}());

$(MyApp.init);

Dans les Modèles, des Collections, des Routeurs et des points de Vue, je travail comme d'habitude, mais alors besoin de s'inscrire que de la classe à la fin du fichier de sorte qu'il pourrait être instancié à un moment plus tard (sans encombrer l'espace de noms) avec:

MyApp.reg('Models', 'App', Model);

Cela vous semble comme un inutile façon d'organiser le code? D'autres ont de meilleurs exemples de la façon d'organiser de très gros projets avec de nombreux Routeurs, des Collections, des Modèles et des points de Vue?

32voto

nrabinowitz Points 27991

J'ai récemment travaillé sur un projet Backbone appelé GapVis (code ici, contenu rendu ici). Je ne sais pas si c'est "vraiment important", mais c'est grand-ish et relativement complexe - 24 classes de vue, 5 routeurs, etc. Il peut être la peine de prendre un coup d'oeil, mais je ne sais pas que toutes mes démarches seront pertinentes. Vous pouvez voir une partie de ma réflexion dans la longue intro commentaire dans mon principal app.js fichier. Quelques clés de choix architecturaux:

  • J'ai un singleton State modèle qui contient tout état actuel de l'info - le point de vue actuel, ce que les id de modèle que nous étudions, etc. Chaque vue qui a besoin de modifier l'état de l'application n'en définissant des attributs sur l' State, et chaque vue qui doit répondre de l'état à l'écoute que modèle pour des événements. Ceci est vrai même pour les vues qui modifient l'état et à mettre à jour l'INTERFACE utilisateur de gestionnaires d'événements dans events jamais re-rendre la vue, ce qui est fait, au contraire, par la liaison de rendre les fonctions de l'état. Ce modèle a vraiment aidé à garder les points de vue séparés les uns des autres - vues ne jamais appeler une méthode sur un autre point de vue.

  • Mes routeurs sont traités comme des vues spécialisées - ils répondre à des événements de l'UI (c'est à dire en tapant une URL) par la mise à jour de l'état, et ils répondent à des modifications de l'état par la mise à jour de l'INTERFACE utilisateur (c'est à dire changer l'URL).

  • Je fais plusieurs choses similaires à ce que vous proposez. Mon espace de noms a un init fonction similaire à la vôtre, et un settings objet de constantes. Mais j'ai mis la plupart de modèle et de vue des classes dans l'espace de bien, parce que j'avais besoin de les mentionner dans plusieurs fichiers.

  • J'utilise un système d'enregistrement pour mes routeurs, et considéré comme l'un de mes points de vue, comme une belle façon de garder les "master classes" (AppRouter et AppView) d'avoir à être conscient de chaque vue. Dans l' AppView des cas, cependant, il s'est avéré que l'ordre de vues enfant était important, donc j'ai fini de coder en dur ces classes.

J'ai peine à le dire que c'était la "bonne" façon de faire les choses, mais il a travaillé pour moi. J'espère que c'est utile - j'ai également eu de la difficulté à trouver visibles-source des exemples de grands projets à l'aide de la Dorsale, et avait pour résoudre la plupart de ce que j'avançais.

13voto

jaydoubleyou Points 126

Ces 2 ressources m'ont aidé à installer mes applications principales sur un sous-sol solide:

5voto

Mauvis Ledford Points 12424

J'ai de l'espace de noms similaires à ce que vous êtes en train de faire (au moins pour les classes de la partie) et tous mes modèles, vues et contrôleurs ressembler à ceci:

views/blocks.js:

(function(cn){
    cn.classes.views.blocks = cn.classes.views.base.extend({

        events: {},

        blocksTemplate: cn.helpers.loadTemplate('tmpl_page_blocks'),

        initialize: function(){
        },

        render: function(){
            $(this.el).html(this.blocksTemplate());
        },

        registerEvents: function(){},
        unregisterEvents: function(){}
    });
})(companyname);

Mon JavaScript espace de noms ressemble à ça, bien que je ne l'améliorer à chaque fois que je créer une nouvelle application:

 companyname:{                                                                                                                                                                                 
   $: function(){},      <== Shortcut reference to document.getElementById                                                                                                                      
   appView: {},          <== Reference to instantiated AppView class.                                                                                                                           
   classes = {           <== Namespace for all custom Backbone classes.                                                                                                                         
     views : {},                                                                                                                                                                                
     models : {},                                                                                                                                                                               
     collections: {},                                                                                                                                                                           
     controllers : {},                                                                                                                                                                          
     Router: null                                                                                                                                                                               
   },                                                                                                                                                                                           
   models: {},          <== Instantiated models.                                                                                                                                                
   controllers: {},     <== Instantiated controllers.                                                                                                                                           
   router: {},          <== Instantiated routers.                                                                                                                                               
   helpers: {},         <== Reusable helper platform methods.                                                                                                                                   
   currentView: {},     <== A reference to the current view so that we can destroy it.                                                                                                          
   init: function(){}   <== Bootstrap code, starts the app.                                                                                                                           
 } 

Tout ce que je veux tous mes points de vue à l'avoir, je l'ai mis dans la vue de base. Mon contrôleur d'appel registerEvents sur tout nouveau point de vue, il crée (après le rendu) et unregisterEvents sur une vue juste avant qu'il ne la tue. Pas toutes les vues de ces deux méthodes supplémentaires de sorte qu'il vérifie d'abord l'existence.

N'oubliez pas que tous les points de vue de venir avec un this.el.remove(); construit dans. Qui non seulement tue les vues élément conteneur, mais se délie tous les événements attachés à elle. Selon la façon dont vous créez vos points de vue par le biais de votre contrôleur, vous ne pouvez pas réellement envie de tuer l'élément et le faire.el.unbind() au lieu de séparer tous les événements.

5voto

fejustin Points 516

En fait, dans les différents moyens ont des avantages et des inconvénients de différentes façons.La chose la plus importante est de trouver un moyen approprié de l'organisation des fichiers.Ce qui suit est l'organisation du projet, je suis actuellement en train de faire. De cette façon, l'accent sera le même module, les fichiers sont placés dans un dossier. Par exemple: les gens module ce module, tous les fichiers sont placés dans des modules / base / répertoire populaire. Après la mise à jour et la maintenance de ce module, seulement le besoin de se concentrer sur les fichiers de ce répertoire sur la ligne, n'affectera pas les fichiers en dehors du répertoire, et l'amélioration de la maintenabilité.

J'espère que ma réponse peut vous aider, j'espère que vous avez quelques précieux conseils.

enter image description here

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