2012-08-14 7 views
7

Ich bin neu bei backbone.js, und auch etwas Neues im Front-End-Bereich und habe noch nicht ganz herausgefunden, wie der Lebenszyklus funktioniert.Lebenszyklus einer Backbone.js Ansicht während ihrer Erstellung

Wir haben ein Django-Backend, das uns HTML-Templates liefert, die wir im Grunde nur als Frames verwenden. Die gesamte Logik wird in Backbone-Ansichten behandelt.

Das Problem, das ich derzeit habe, ist, dass ich versuche, ein Diagramm zu zeichnen, aber die Grafikfunktion findet die Ansicht nicht basierend auf der ID, da es nicht während der Renderfunktion existiert, aber ich bin mir nicht bewusst eines Weges, dies in einer späteren Phase zu erreichen.

Ich habe versucht, die Ansicht manuell in Chrome-Konsole zu erstellen, nachdem die Seite vollständig geladen hat und es funktioniert:

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

The View:

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'] 
    }); 
}, 

});

Wo es erstellt:

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

Könnte mir jemand klären:

  1. Wie Backbone tatsächlich die Schaffung einer Ansicht umgehen? Was sind die verschiedenen Phasen?
  2. Wie soll ich mit dieser Situation umgehen, z.B. an welcher stelle meines code würde das element aus der html-template existieren, damit ich die grafikfunktion dafür aufrufen könnte?
  3. Oder ist meine Architektur nur grundlegend fehlerhaft? Soll ich das auf eine ganz andere Art und Weise versuchen?

Antwort

11

FWIW, ich denke, Sie sind auf dem richtigen Weg. Aber wie Ihre Frage bemerkt, haben Sie nur ein paar Dinge außer Betrieb.

Streng genommen ist in den Backbone-Ansichten nicht viel von einem Lebenszyklus integriert. Wenn Sie einen instanziieren, ruft er initialize auf. Darüber hinaus liegt es an Ihnen zu entscheiden, wie der Lebenszyklus der Ansicht aussehen wird. Wann wird es gerendert? Wenn das gerenderte el an das DOM angehängt wird, wenn es aus dem DOM entfernt wird, wenn es geschlossen und zerstört wird. Das hängt davon ab, wie Sie mit der Ansicht arbeiten möchten.

Es gibt einige Dinge, die Sie tun und hinzufügen, um diesen Lebenszyklus natürlich leichter verständlich zu machen. Es gibt einige großartige Frameworks, die zum Beispiel auf dem Backbone sitzen. Ich empfehle, LayoutManager, Thorax, Chaplin und meine eigene Marionette als Ausgangspunkt dafür zu betrachten.

Mehr auf den Punkt Ihrer Frage, obwohl, das Plugin, das Sie beschreiben, ist sehr wahrscheinlich abhängig von den HTML-Elementen im DOM, bevor das Plugin ausgeführt werden kann. Dies ist für visuelle Plugins üblich, da sie häufig Standortinformationen, CSS-Informationen, Positionen relativer Elemente usw. erfassen müssen.

Es gibt einige sehr einfache Dinge, die Sie tun können, um diese Plugins zu vereinfachen und dies zum Funktionieren zu bringen. Ich habe ein wenig darüber gebloggt, hier: http://lostechies.com/derickbailey/2012/02/20/using-jquery-plugins-and-ui-controls-with-backbone/ - hoffentlich hilft das euch den Weg zu finden.

Genauer gesagt, was Sie sehen wollen, ist die Idee einer onShow Methode. Dies ist keine Methode, die Backbone eigenständig versteht. Dieses Konzept müssen Sie Ihren Ansichten und Apps hinzufügen. Aber die gute Nachricht ist, dass es einfach ist. Fügen Sie einfach die Methode zu Ihrer Ansicht hinzu und rufen Sie sie dann zur richtigen Zeit an:

Hoffe, dass hilft.

+0

Ich war in der Lage, das Problem zu lösen, indem ich explizit die render-Funktion aufgerufen habe, nachdem das ChartView erstellt und an seinen Elternknoten angehängt wurde: 'chartWidgetView.contentView.Render();'. Vielen Dank für die hervorragende Einsicht und den Link, ich werde das auf jeden Fall für die Zukunft beachten! Und ich werde auch meinen Code etwas umgestalten;) – jesseniem

1

Ich denke nur, dass das Problem ist, dass die Vorlage nicht vom Server zurückgegeben wird, bevor Sie es rendern, daher wird es nicht angezeigt. Sie können dieses Problem mit dem Objekt deferred von jQuery umgehen (siehe this ref). Versuchen Sie etwas zu tun, wie am Ende des initialize:

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

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

Siehe auch Derick Bailey Artikel über deferreds in Backbone.js: http://lostechies.com/derickbailey/2012/02/09/asynchronously-load-html-templates-for-backbone-views/

+0

Ich war nicht in der Lage, das Problem zu lösen. +1 für die ausgezeichnete Verbindung. – jesseniem

1

Sie die el Schaffung, aber nicht auf das DOM Befestigung und ich vermute, dass das Diagramm nur das DOM nach dem Element durchsucht, an das es sich anfügt. Sie müssen es vor dem Aufruf von drawGraph an DOM anhängen.

Wie für die Erstellung der Backbone-Ansicht, denke ich, der beste Weg, um eine eingehende Ansicht zu erhalten, ist einfach den annotierten Quellcode zu lesen, der tatsächlich nicht so lang ist.

+0

Wird dies an das DOM angehängt: 'this. $ El.append (compiledTemplate);'? Oder ist es nur bei 'this. $ el.append (chartWidgetView.el);' dass die Vorlage tatsächlich Teil des DOM wird? – jesseniem

+0

In beiden Fällen wird die Vorlage an die Backbone-Ansicht angehängt. Wenn das el zu diesem Zeitpunkt an das DOM angehängt ist, dann ist das auch die Vorlage. In diesem Fall wird el nur im letzteren Fall an das DOM angehängt. – tsiki

Verwandte Themen