Backbone.View "el" Verwirrung

97

Wie soll mit einer Ansicht elumgegangen werden? Es muss eingestellt werden, sonst werden keine Ereignisse ausgelöst (siehe hier ).

Aber sollte es ein Element sein, das bereits auf der Seite ist? In meiner App rendere ich eine Vorlage (jQuery Templates) in eine Fancybox. Was soll das elin diesem Fall sein?

Manuel Meurer
quelle
11
Ich dachte - ich bin der einzige, der mit dem elDing spielt.
Yugal Jindle
elist wie gf. niemand kann sie vollständig verstehen.
Mahi

Antworten:

121

In einer Ansicht el findet die gesamte Ereignisbindung statt. Sie müssen es nicht verwenden, aber wenn Sie möchten, dass das Backbone Ereignisse auslöst, müssen Sie Ihre Rendering-Arbeit am el ausführen. Eine Ansicht el ist ein DOM-Element, muss jedoch kein bereits vorhandenes Element sein. Es wird erstellt, wenn Sie keine von Ihrer aktuellen Seite ziehen, aber Sie müssen sie in die Seite einfügen, wenn Sie jemals möchten, dass sie etwas bewirkt.

Ein Beispiel: Ich habe eine Ansicht, die einzelne Elemente erstellt

window.ItemView = Backbone.View.extend({
    tagName: "li", //this defaults to div if you don't declare it.
    template: _.template("<p><%= someModelKey %></p>"),
    events: {
         //this event will be attached to the model elements in
         //the el of every view inserted by AppView below
        "click": "someFunctionThatDoesSomething"
    },
    initialize: function () { 
        _.bindAll(this, "render");
        this.render();
    },
    render: function () {
        this.el.innerHTML = this.template(this.model.toJSON());
        return this;
    }
});
window.AppView = Backbone.View.extend({
    el: $("#someElementID"), //Here we actually grab a pre-existing element
    initialize: function () { 
        _.bindAll(this, "render");
        this.render(new myModel());
    },
    render: function (item) { 
        var view = new ItemView({ model: item });
        this.el.append(view.render().el);
    }
});

In der ersten Ansicht werden nur die Listenelemente erstellt, und in der zweiten Ansicht werden sie tatsächlich auf der Seite platziert. Ich denke, das ist ziemlich ähnlich zu dem, was im ToDo-Beispiel passiert auf der backbone.js-Site . Ich denke, Konvention ist es, Sie Inhalt in die el zu machen. Das el dient also als Landeplatz oder Container zum Platzieren Ihrer Vorlageninhalte. Das Backbone bindet dann seine Ereignisse an die darin enthaltenen Modelldaten.

Wenn Sie eine Ansicht erstellen , können Sie die el in vier Möglichkeiten , mit manipulieren el:, tagName:, className:, und id:. Wenn keines davon deklariert ist, ist el standardmäßig ein Div ohne ID oder Klasse. Es ist zu diesem Zeitpunkt auch nicht mit der Seite verknüpft. Sie können das Tag mithilfe von tagName in etwas anderes ändern (z. B. erhalten tagName: "li"Sie ein el von <li></li>). Sie können die ID und Klasse von el ebenfalls festlegen. Trotzdem ist el kein Teil Ihrer Seite. Mit der Eigenschaft el können Sie das el-Objekt sehr feinkörnig bearbeiten. Die meiste Zeit benutze ich eineel: $("someElementInThePage")Dies bindet tatsächlich alle Manipulationen, die Sie an el in Ihrer Ansicht vornehmen, an die aktuelle Seite. Wenn Sie andernfalls sehen möchten, dass all die harte Arbeit, die Sie in Ihrer Ansicht geleistet haben, auf der Seite angezeigt wird, müssen Sie sie an einer anderen Stelle in Ihrer Ansicht einfügen / an die Seite anhängen (wahrscheinlich beim Rendern). Ich stelle mir el gerne als den Container vor, den all Ihre Ansichten manipulieren.

LeRoy
quelle
Danke für die Klarstellung und das Beispiel! Ich denke, es ist nicht immer klar, was der El in bestimmten Situationen sein sollte und der Entwickler muss ein "Gefühl" dafür bekommen. Ihre Erklärungen haben sicherlich geholfen! Eine Frage: Sie definieren kein el in Ihrer ItemView, sondern greifen über die Renderfunktion darauf zu. Ob das funktioniert? Gibt es eine Art Standard-El, wenn Sie es nicht explizit definieren?
Manuel Meurer
3
Standardmäßig ist el ein "div" -Tag ohne ID oder Klasse. Es ist ein DOM-Objekt, das nicht an Ihr Seiten-DOM gebunden ist. Normalerweise füge ich es in die Renderfunktion oder die Renderfunktion einer übergeordneten Ansicht ein / hänge es an die Seite an.
LeRoy
Meine Antwort wurde mit einer Beschreibung der Eigenschaften aktualisiert, die das el definieren.
LeRoy
5
Ich denke, mein einziges Problem beim Abrufen eines bereits vorhandenen Elements mit el: $ ("# someElementID") ist, dass Ihre Ansicht wahrscheinlich mehr weiß als es sollte, was es schwierig macht, es wiederzuverwenden. siehe "Ansicht von DOM entkoppeln
Scott Coates
@scoarescoare Da Sie die Eigenschaft el bei der Instanziierung hinzufügen, weiß die Ansicht selbst nicht mehr als sie sollte. Sie bleibt modular und kann alle $ (el) akzeptieren, die Sie übergeben möchten. Das macht es also wirklich ziemlich wiederverwendbar.
Metagrapher
6

Jetzt etwas alt, aber ich war auch verwirrt, und für andere Leute, die hierher kommen, könnte diese Geige helfen - http://jsfiddle.net/hRndn/2/

var MyView = Backbone.View.extend({

    events: {
        "click .btn" : "sayHello",
    },

    sayHello : function() {
        alert("Hello");
    },


    render : function() {
        this.$el.html("<input type='button' class='btn' value='Say Hello'></input>");

    }
});

$(function() {
    myView = new MyView({el:"#parent_id"});
    myView.render();
});
Kennzeichen
quelle
Ich bin diesem Modell gefolgt und wünschte, ich hätte es nicht getan. Um eine Ansicht zu zerstören und die Bindungen zu entfernen, lautet die Konvention des Backbones view.remove (). Dadurch wird $ el zerstört und aus dem DOM entfernt. Wenn Sie die Ansicht erneut anzeigen müssen, ist $ el nicht vorhanden.
JJ
@Mark was Wenn ich eine zusammengesetzte Architektur wie Marionette verwende ... muss ich immer noch die el von view haben?
Afr0
Ihr Geigencode
Izzy
@ Mahi Ja du hast recht. Ich habe wahrscheinlich einen falschen Link eingefügt, sorry. Dieser funktioniert: jsfiddle.net/hRndn/127
Izzy
1

Sie möchten, dass Ihr 'el' auf ein Element verweist, das ein untergeordnetes Element enthält, das ein Ereignis enthält, das eine Änderung in Ihrer Ansicht auslöst. Könnte so breit sein wie ein "body" -Tag.

Joshvermaire
quelle
Hmm, das klärt es auch nicht wirklich auf. In den meisten Fällen befinden sich die Elemente, die eine Änderung in meiner Ansicht auslösen könnten, in der Vorlage, die von der Ansicht gerendert wird. Daher sind diese Elemente vor dem Rendern noch nicht vorhanden.
Manuel Meurer