Anhängen von Ansichten von backbone.js an vorhandene Elemente im Vergleich zum Einfügen von el in das DOM

72

Ich implementiere meine erste tatsächliche Backbone-App, die kein Tutorial ist, und habe zwei Fragen zu einem Aspekt der Verwendung von backbone.js, der bei mir nicht sehr gut ankommt. Dies bezieht sich auf das Einfügen einer gerenderten Ansicht elin das DOM im Vergleich zur Verwendung ein vorhandenes Element für el. Ich vermute, ich werde Ihnen hier alle ein paar "lehrbare Momente" bieten und die Hilfe schätzen.

Die meisten Beispiele für die Backbone-Ansicht, die ich im Web sehe, geben beim Erstellen einer Ansicht tagName, id und / oder className an und erstellen dabei ein el, das nicht mit dem DOM verbunden ist. Sie sehen normalerweise so aus:

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

In den Tutorials wird jedoch nicht immer erklärt, wie empfohlen wird, das gerenderte El in das DOM aufzunehmen. Ich habe es auf verschiedene Arten gesehen. Meine erste Frage lautet also: Wo ist der geeignete Ort, um die Rendermethode einer Ansicht aufzurufen und ihr el in das DOM einzufügen? (nicht unbedingt ein und derselbe Ort). Ich habe es in einem Router, in den Initialisierungs- oder Renderfunktionen der Ansicht oder einfach in einer Dokumentbereitschaftsfunktion auf Stammebene gesehen. ( $(function ()). Ich kann mir vorstellen, dass eine dieser Arbeiten funktioniert, aber gibt es einen richtigen Weg, dies zu tun?

Zweitens beginne ich mit HTML-Markup / Wireframe und konvertiere HTML-Teile in JS-Vorlagen, die Backbone-Ansichten entsprechen. Anstatt die Ansicht ein nicht angefügtes Element rendern zu lassen und einen Ankerpunkt im HTML-Code bereitzustellen, um es einzufügen, empfinde ich es als natürlicher, wenn es nur ein Element für eine Ansicht gibt und es nicht verschwindet. ein vorhandenes, geleertes Wrapper-Element (häufig ein divoder span) als das elselbst zu verwenden. Auf diese Weise muss ich mich nicht darum kümmern, den Platz im Dokument zu finden, an dem ich mein nicht angebrachtes el einfügen kann, was möglicherweise so aussehen würde (beachten Sie die zusätzliche Überlagerung):

<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>

Ein Teil meiner zweiten Frage lautet also: Ist für eine grundsätzlich statische Ansicht etwas falsch daran, ein vorhandenes Element aus dem HTML-Code der Seite direkt als meine Ansicht zu verwenden el? Auf diese Weise weiß ich, dass es sich bereits im DOM an der richtigen Stelle befindet und dass beim Aufrufen von Rendern die Ansicht auf der Seite sofort gerendert wird. Ich würde dies erreichen, indem ich das bereits vorhandene Element als 'el' an den Konstruktor meiner Ansicht weitergebe. Auf diese Weise muss ich mir keine Sorgen machen, dass ich es in das DOM stecke (was Frage 1 in Frage stellt), und wenn ich render aufrufe, wird das DOM sofort aktualisiert. Z.B

<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>

Ist dies eine gute Möglichkeit für statische Ansichten auf der Seite? Das heißt, es gibt nur eine dieser Ansichten, und sie wird unter keinen Umständen verschwinden. Oder gibt es einen besseren Weg? Mir ist klar, dass es verschiedene Möglichkeiten gibt, Dinge zu tun (z. B. in einem Router, in einer übergeordneten Ansicht, beim Laden von Seiten usw.), je nachdem, wie ich eine Ansicht verwende, aber im Moment betrachte ich das anfängliche Laden von Seiten Anwendungsfall.

Vielen Dank

B Robster
quelle

Antworten:

54

An der Idee, eine Ansicht an einen vorhandenen DOM-Knoten anzuhängen, ist absolut nichts auszusetzen.

Sie können das el sogar einfach als Eigenschaft in Ihre Ansicht aufnehmen.

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();
});

Ich empfehle, das zu tun, was funktioniert ... Das Schöne an Backbone ist, dass es flexibel ist und Ihren Anforderungen entspricht.

In Bezug auf gängige Muster habe ich im Allgemeinen eine Hauptansicht, um Überansichten zu verfolgen, dann möglicherweise eine Listenansicht und einzelne Elementansichten.

Ein weiteres gängiges Muster für die Initialisierung besteht darin, eine Art App-Objekt zum Verwalten von Inhalten zu haben ...

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

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

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

Wie ich bereits sagte, gibt es wirklich keine falsche Art, Dinge zu tun, nur das zu tun, was funktioniert. :) :)

Fühlen Sie sich frei, mich auf Twitter @ jcreamer898 zu kontaktieren, wenn Sie weitere Hilfe benötigen. Schauen Sie sich auch @derickbailey an, er ist eine Art BB-Guru.

Habe Spaß!

jcreamer898
quelle
1
Vielen Dank auch für den Tipp zur Verwendung des Modulmusters. Ich habe mit require.js geflirtet, um Module und dynamisches Laden und all das Gute zu implementieren, aber wir verwenden so viele Nicht-AMD-Plugins und vorhandenen Code, dass ich denke, dass es wahrscheinlich einfacher und weniger fehleranfällig ist, es einfach zu behalten Dinge in Dateien und Modulen, die Sinn machen, verwenden Sie, wenn möglich, so etwas wie das oben angegebene Modulmuster und konzentrieren / minimieren Sie sie für die Produktion.
B Robster
1
Auf jeden Fall ist require.js eine großartige Lösung, aber es kann definitiv schwierig sein. Normalerweise verwende ich nur Muster wie das Modulmuster und dann den Namespace, um Dinge aus dem Fenster zu halten. Froh, dass ich helfen konnte!
jcreamer898
Vielen Dank für den Hinweis in die richtige Richtung. Fand auch heraus, dass $ (this.el) nicht so funktioniert wie das. $ El
Aleksy Goroszko
@AleksyGoroszko wie ist das. $ El unterscheidet sich von $ (this.el)?
jcreamer898
18

Sie können auch ein HTML-DOM-Element-Objekt als 'el'-Eigenschaft der Optionen in die Ansicht senden.

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')
    });
});
andho
quelle
4
Genau die Antwort, nach der ich gesucht habe. Vielen Dank!
Zachwill