2012-08-14 26 views
7

Soy nuevo en backbone.js, y algo nuevo en el trabajo de front-end también y todavía no he descubierto cómo funciona el ciclo de vida.Ciclo de vida de una Backbone.js Ver durante su creación

Tenemos un back-end Django, que nos proporciona plantillas html, que básicamente solo utilizamos como marcos. Toda la lógica se maneja en vistas de Backbone.

El problema que tengo actualmente es que estoy tratando de dibujar un gráfico pero la función de representación gráfica no encuentra la vista basada en el ID, ya que no existe durante la función de renderizado, pero no estoy al tanto de una manera de lograr esto en una fase posterior.

He tratado de crear la vista de forma manual en la consola de cromo después de la página se haya cargado completamente y funciona:

var main = new MainView(); 
    main.showChart(); 

La Vista:

var ChartView = Backbone.View.extend({ 

    title: 'Chart', 

    initialize: function() { 

    // This assures that this refers to this exact view in each function 
    // (except within asynchronous functions such as jquery each) 
    _.bindAll(this); 

    // Saving parameters given by parent 
    this.index = this.options.index; 

    // Retrieve the template from server 
    var template = _.template(getTemplate('chart.html')); 

    // Compile the template with given parameters 
    var compiledTemplate = template({'title': this.title}); 

    // Set the compiled template to this instance's el-parameter 
    this.$el.append(compiledTemplate); 

    // Rendering the view 
    this.render(); 
}, 

    render: function() { 

    var self = this; 

    // Draw the graph when the page is ready 
    $(function(){ 
     self.drawGraph('chart1', this.line1Data); 
    }); 

    // Render function should always return the instance 
    return this; 
}, 

drawGraph : function(chartId, lineData) { 

    Morris.Line({ 
      element: chartId, 
      data: [ 
      {y: '2012', a: 100}, 
      {y: '2011', a: 75}, 
      {y: '2010', a: 50}, 
      {y: '2009', a: 75}, 
      {y: '2008', a: 50}, 
      {y: '2007', a: 75}, 
      {y: '2006', a: 100} 
      ], 
      xkey: 'y', 
      ykeys: ['a'], 
      labels: ['Series A'] 
    }); 
}, 

});

donde es creado:

 var chartWidgetView = new WidgetView({'contentView': new ChartView()}); 
    this.initializeWidget(chartWidgetView); 
    this.$el.append(chartWidgetView.el); 

Podría alguien explicar a mí:

  1. ¿Cómo Backbone manejar realmente la creación de un punto de vista? ¿Cuáles son las diferentes etapas?
  2. ¿Cómo debo manejar esta situación, p. ¿en qué punto de mi código existiría el elemento de la plantilla html para poder llamar a la función de gráficos para ello?
  3. ¿O mi arquitectura es fundamentalmente defectuosa? ¿Debo tratar de hacer esto de una manera completamente diferente?

Respuesta

11

FWIW, creo que estás en el camino correcto. Pero como señala su pregunta, acaba de tener algunas cosas fuera de orden.

Estrictamente hablando, no hay mucho de un ciclo de vida integrado en las vistas de la red troncal. Cuando crea una instancia, llama a initialize. Aparte de eso, depende de usted decidir cuál será el ciclo de vida de la vista. Cuando será renderizado Cuando el el prestado se adjuntará al DOM, cuando se eliminará del DOM, cuando se cerrará y se destruirá. Todo depende de cómo quiera trabajar con la vista.

Hay algunas cosas que hacer y agregar para hacer este ciclo de vida más fácil de entender, por supuesto. Hay algunos grandes marcos que se encuentran en la parte superior de la columna vertebral, por ejemplo. Recomiendo buscar en LayoutManager, Thorax, Chaplin y mi propia Marioneta como puntos de partida para esto.

Más al punto de su pregunta, sin embargo, es muy probable que el complemento que está describiendo dependa de los elementos HTML que se encuentran en el DOM antes de poder ejecutar el complemento. Esto es común para los complementos visuales, ya que a menudo necesitan capturar información de ubicación, información css, posiciones de elementos relativos, etc.

Hay algunas cosas muy simples que puede hacer para facilitar este tipo de complementos y hacer que esto funcione. He escrito un blog sobre esto un poco, aquí: http://lostechies.com/derickbailey/2012/02/20/using-jquery-plugins-and-ui-controls-with-backbone/ - espero que eso te ayude a seguir el camino.

Específicamente, lo que querrá ver es la idea de un método onShow. Este no es un método que el Backbone entiende por sí mismo. Es un concepto que tendrá que agregar a sus puntos de vista y sus aplicaciones. Pero la buena noticia es que es fácil. Simplemente agregue el método a su vista, luego llámelo en el momento correcto:


var AnotherView = Backbone.View.extend({ 
    onShow: function(){ 
    this.$el.layout({ appDefaultStyles: true}); 
    } 
}); 


// instantiate the view 
var view = new AnotherView(); 

// render it 
view.render(); 

// attach it to the DOM 
$("#someDiv").html(view.el); 

// now that it has been attached to the DOM 
// you can call your DOM-dependent plugins 
view.onShow(); 

Espero que ayude.

+0

Pude resolver el problema llamando explícitamente a la función de renderizado después de que ChartView se haya creado y anexado a su elemento primario: 'chartWidgetView.contentView.render();'. Gracias por la excelente visión y el enlace, definitivamente los tendré en cuenta para el futuro. Y también voy a refactorizar mi código un poco;) – jesseniem

1

Solo echando un vistazo a esto, creo que el problema es que la plantilla no se devuelve desde el servidor antes de representarla, por lo tanto, no aparece. Puede solucionar este problema utilizando el objeto deferred de jQuery (consulte this ref). Trate de hacer algo así como al final de initialize:

this.deferredTemplate = $el.append(compiledTemplate); 

this.deferredTemplate.done(function() { 
    this.render(); 
}); 

Véase también el artículo de Derick Bailey en deferreds en Backbone.js: http://lostechies.com/derickbailey/2012/02/09/asynchronously-load-html-templates-for-backbone-views/

+0

No he podido resolver el problema con esto. +1 para el excelente enlace sin embargo. – jesseniem

1

Estás creando la EL, pero no lo conecta a la DOM, y yo sospeche que el cuadro solo busca el DOM para que el elemento se una. Debe adjuntarlo a DOM antes de llamar al drawGraph.

En cuanto a la creación de la vista Backbone, creo que la mejor manera de obtener una vista en profundidad es simplemente leer el código fuente anotado, que en realidad no es tan largo.

+0

Esto lo asocia al DOM: 'this. $ El.append (compiledTemplate);'? ¿O es solo en 'this. $ El.append (chartWidgetView.el);' que la plantilla realmente se convierte en parte del DOM? – jesseniem

+0

Ambos casos adjuntan la plantilla a la vista de Backbone. Si el el está unido al DOM en ese punto, entonces también lo está la plantilla. En este caso, solo en el último caso, el está unido al DOM. – tsiki

Cuestiones relacionadas