2012-05-24 10 views
70

Estoy implementando mi primera aplicación Backbone no tutorial, y tengo 2 preguntas simples sobre un aspecto del uso del uso de backbone.js que no se está resolviendo muy bien conmigo, que se refiere a la inyección de una vista prestados el en el DOM vs. utilizando un elemento existente para el. Sospecho que les proporcionaré a todos ustedes algunos "momentos de enseñanza" aquí, y agradezco la ayuda.adjuntando vistas de backbone.js a los elementos existentes frente a insertar el en el DOM

La mayoría de los ejemplos de Backbone View que veo en la web especifican tagName, id y/o className, al crear una vista y crear así un el que no está vinculado desde el DOM. Por lo general se ven algo como:

App.MyView = Backbone.View.extend({ 
    tagName: 'li', 
    initialize: function() { 
    ... 
    }, 
    render: function() { 
     $(this.el).html(<render an html template>); 
     return this; 
    } 
}); 

Pero los tutoriales no siempre reciben en torno a la explicación de cómo se recomiendan obtener el EL rendido en el DOM. Lo he visto de diferentes maneras. Entonces, mi primera pregunta es: ¿dónde está el lugar apropiado para llamar al método de renderización de una vista e insertar su el en el DOM? (no necesariamente uno y el mismo lugar). Lo he visto hecho en un enrutador, en las funciones de inicialización o renderización de la vista, o simplemente en una función de documento preparado para el nivel raíz. ($(function()). Me imagino que cualquiera de estos trabajos, pero ¿hay una forma correcta de hacerlo?

En segundo lugar, estoy empezando con algunos HTML markup/wireframe, y la conversión de porciones html a js plantillas correspondientes a las vistas de la red troncal. En lugar de dejar que la vista represente un elemento desacoplado y proporcionar un punto de anclaje en el html para pegarlo, siento que es más natural, cuando solo va a haber un elemento para una vista y no va a desaparecer, para usar un elemento de envoltura vacío existente (a menudo un div o span) como el el en sí mismo. De esa forma, no tiene que preocuparse por encontrar el lugar en el documento para insertar mi ataduras EL, lo que potencialmente podría terminar pareciéndose a esto (tenga en cuenta la estratificación adicional):

<div id="insert_the_el_in_here"> <!-- this is all that's in the original HTML doc --> 
    <div id="the_el"> <!-- i used to be a backbone generated, unattached el but have been rendered and inserted --> 
     <!-- we're finally getting to some useful stuff in here --> 
    </div> 
</div> 

Así que parte de mi segunda pregunta es decir, para una vista básicamente estática, ¿hay algún problema con el uso de un elemento existente del HTML de la página directamente como mi vista el? De esta forma, sé que ya está en el DOM, en el lugar correcto, y que la invocación de renderizará inmediatamente la vista en la página. Me gustaría lograr esto pasando el elemento ya exixting al constsructor de mi vista como 'el'. De esta forma, me parece, no tengo que preocuparme de incluirlo en el DOM (lo que hace que la pregunta 1 sea discutible), y la invocación de renderizado actualizará inmediatamente el DOM. P.ej.

<form> 
    <div someOtherStuff> 
    </div> 
    <span id="myView"> 
    </span> 
</form> 

<script type="text/template" id = "myViewContents"> . . . </script> 

<script type="application/javascript"> 
window.MyView = Backbone.View.extend({ 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      $(this.el).html(this.template()); 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView({ el: $('#myView').get(0) }); 
}); 
</script> 

¿Es esta una manera correcta de hacerlo para vistas estáticas en la página? es decir, solo hay una de estas vistas, y no desaparecerá bajo ninguna circunstancia. ¿O hay un mejor camino? Me doy cuenta de que puede haber diferentes maneras de hacer las cosas (es decir, en un enrutador, en una vista principal, en la carga de la página, etc.) en función de cómo estoy usando una vista, pero ahora estoy mirando la carga de la página inicial caso de uso

Gracias

Respuesta

53

no hay absolutamente nada de malo con la idea de unir el fin de un nodo DOM existente.

Incluso puede poner simplemente el el como propiedad en su vista.

window.MyView = Backbone.View.extend({ 
    el: '#myView', 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      this.$el.html(this.template()); // this.$el is a jQuery wrapped el var 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView(); 
}); 

Lo que recomiendo es, haga lo que funciona ... La belleza de Backbone es que es flexible y satisfará sus necesidades.

Por lo que respecta a los patrones comunes, generalmente tengo una vista principal para realizar un seguimiento de las vistas, luego una vista de lista y vistas de elementos individuales.

Otro patrón común en lo que se refiere a la inicialización es tener algún tipo de objeto Aplicación para gestionar cosas ...

var App = (function ($, Backbone, global) { 
    var init = function() { 
     global.myView = new myView(); 
    }; 

    return { 
     init: init 
    }; 
}(jQuery, Backbone, window)); 

$(function() { 
    App.init(); 
}); 

Como he dicho antes, sin embargo, no hay realmente ninguna manera incorrecta de hacer las cosas, simplemente haz lo que funciona :)

No dude en contactarme en twitter @ jcreamer898 si necesita más ayuda, también echa un vistazo a @derickbailey, es una especie de gurú de BB.

¡Diviértete!

+1

Además, gracias por la sugerencia sobre el uso del patrón del módulo. He estado coqueteando con require.js como una forma de implementar módulos y carga dinámica y todas esas cosas buenas, pero utilizamos tantos plugins que no son de AMD y código existente que creo que es probablemente más simple y menos propenso a errores simplemente para mantener cosas en archivos y módulos que tienen sentido, utilice algo así como el patrón del módulo que indica arriba, cuando sea posible, y concat/minify para la producción. –

+1

Absolutamente, require.js es una gran solución, pero definitivamente puede ser complicado. Usualmente usaré patrones como el patrón del módulo y luego usaré el espacio de nombres para mantener las cosas fuera de la ventana. ¡Me alegro de poder ayudar! – jcreamer898

+0

Gracias por apuntar en la dirección correcta. También descubrió que $ (this.el) no funciona de la misma manera que este. $ El –

18

También puede enviar un objeto HTML DOM element a la vista como la propiedad 'el' de las opciones.

window.MyView = Backbone.View.extend({ 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      this.$el.html(this.template()); // this.$el is a jQuery wrapped el var 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView({ 
     el: document.getElementById('myView') 
    }); 
}); 
+4

Exactamente la respuesta que estaba buscando. ¡Gracias! – zachwill

Cuestiones relacionadas