javascript - template - backbonejs github
Gran organizaciĆ³n de aplicaciones web backbone.js (4)
De hecho, de diferentes maneras tienen ventajas y desventajas de diferentes maneras. Lo más importante es encontrar una forma adecuada de organizar archivos. A continuación se muestra la organización del proyecto que estoy haciendo actualmente. De esta forma, el foco será el mismo módulo: los archivos relacionados se colocan en una carpeta. Por ejemplo: el módulo de personas, este módulo, todos los archivos se colocan en el directorio modules / base / people. Después de actualizar y mantener este módulo, solo debe centrarse en los archivos de este directorio en la línea, no afectará los archivos fuera del directorio y la capacidad de mantenimiento mejorada.
Espero que mi respuesta pueda darte algo de ayuda, espero que tengas algunos consejos valiosos.
Actualmente estoy trabajando en una gran aplicación web construida en backbone.js y he tenido muchos problemas con la organización, "zombies", etc., así que decidí hacer un importante refactor de código. Ya he escrito un montón de funciones de ayuda para tratar con los "zombis"; sin embargo, me gustaría comenzar desde el principio y crear una buena estructura / organización para el código. No he encontrado muchos ejemplos / tutoriales excelentes sobre la organización backbone.js a gran escala, así que de alguna manera comencé desde cero y me gustaría ver si puedo obtener algunas opiniones sobre dónde comencé.
Obviamente he configurado mi código dentro de un espacio de nombres global; pero también me gustaría mantener ese espacio de nombres bastante limpio. Mi app.js principal mantiene los archivos de clase separados del espacio de nombres global; puede registrar una clase (para que pueda ser instanciada) usando la función reg () y la función inst () crea una instancia de la clase. Por lo tanto, además de los 3 métodos, el espacio de nombres MyApp solo tiene enrutador, modelo y vista:
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);
Dentro de los Modelos, Colecciones, Enrutadores y Vistas, trabajo como de costumbre pero luego necesito registrar esa clase al final del archivo para que pueda ser instanciado en un momento posterior (sin saturar el espacio de nombres) con:
MyApp.reg(''Models'', ''App'', Model);
¿Parece esto una forma innecesaria de organizar el código? ¿Otros tienen mejores ejemplos de cómo organizar proyectos realmente grandes con muchos enrutadores, colecciones, modelos y vistas?
Espacio de nombre I similar a lo que estás haciendo (al menos para la parte de clases) y todos mis modelos, vistas y controladores se ven así:
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);
Mi espacio de nombres de JavaScript se ve así, aunque mejoro cada vez que construyo una nueva aplicación:
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.
}
Cualquier cosa que quiera que tengan todos mis puntos de vista, la puse en la vista base. Mi controlador llamará a registerEvents
en cualquier vista nueva que cree (después del renderizado) y unregisterEvents
el unregisterEvents
en una vista justo antes de que la mate. No todas las vistas tienen estos dos métodos adicionales, por lo que primero verifica la existencia.
No olvides que todas las vistas vienen con un this.el.remove();
incorporado. Que no solo mata el elemento contenedor de vistas sino que desvincula todos los eventos asociados. Dependiendo de cómo esté creando sus vistas a través de su controlador, en realidad no desea matar el elemento y hacer esto.el.unbind () para desvincular todos los eventos.
Estos 2 recursos me ayudaron a configurar mis aplicaciones principales en un sólido sótano:
Recientemente trabajé en un proyecto Backbone llamado GapVis ( código aquí , contenido presentado aquí ). No sé si es "realmente grande", pero es grande y relativamente complejo: 24 clases de vista, 5 enrutadores, etc. Puede valer la pena echarle un vistazo, aunque no sé si todos mis enfoques serán pertinente. Puedes ver algunos de mis pensamientos en el comentario introductorio largo en mi archivo principal app.js. Algunas opciones arquitectónicas clave:
Tengo un modelo de
State
singleton que contiene toda la información de estado actual: la vista actual, los ID de modelo que estamos viendo, etc. Cada vista que necesita modificar el estado de la aplicación lo hace mediante el establecimiento de atributos en elState
y cada vista que necesita para responder al estado, escucha ese modelo de eventos. Esto es cierto incluso para las vistas que modifican el estado y la actualización: los manejadores deevents
UI enevents
nunca vuelven a renderizar la vista, esto se hace mediante el enlace de funciones de renderizado al estado. Este patrón realmente ayudó a mantener las vistas separadas unas de otras: las vistas nunca llaman a un método en otra vista.Mis enrutadores se tratan como vistas especializadas: responden a eventos de IU (es decir, escribiendo en una URL) actualizando el estado y responden a cambios de estado actualizando la IU (es decir, cambiando la URL).
Hago varias cosas similares a lo que estás proponiendo. Mi espacio de nombres tiene una función
init
similar a la tuya y un objeto desettings
para constantes. Pero puse la mayoría de las clases de modelo y vista en el espacio de nombres también, porque necesitaba referirme a ellos en varios archivos.Utilizo un sistema de registro para mis enrutadores, y lo considero uno para mis puntos de vista, como una buena manera de mantener las clases "maestras" (
AppRouter
yAppView
) de tener que estar al tanto de cada vista. En el caso deAppView
, sin embargo, resultó que el orden de las vistas de los niños era importante, así que terminé codificando esas clases.
Casi no diría que esta era la forma "correcta" de hacer las cosas, pero funcionó para mí. Espero que sea útil. También tuve problemas para encontrar ejemplos de fuentes visibles de proyectos grandes que usaban Backbone, y tuve que resolver la mayor parte de esto a medida que avanzaba.