Backbone.View "el" confusion

97

Comment une vue doit-elle elêtre gérée? Il doit être défini, sinon les événements ne se déclenchent pas (voir ici ).

Mais devrait-il s'agir d'un élément déjà présent sur la page? Dans mon application, je rend un modèle (jQuery Templates) dans une Fancybox. Que devrait-il elêtre dans ce cas?

Manuel Meurer
la source
11
J'ai pensé - je suis le seul à tripoter la elchose.
Yugal Jindle
elest comme gf. personne ne peut les comprendre pleinement.
Mahi

Réponses:

121

Une vue el est l'endroit où toute la liaison d'événement a lieu. Vous n'êtes pas obligé de l'utiliser, mais si vous voulez que le backbone déclenche des événements, vous devez effectuer votre travail de rendu sur el. Un view el est un élément DOM mais il n'est pas nécessaire qu'il s'agisse d'un élément préexistant. Il sera créé si vous n'en tirez pas un de votre page actuelle, mais vous devrez l'insérer dans la page si jamais vous voulez le voir faire quelque chose.

Un exemple: j'ai une vue qui crée des éléments individuels

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

La première vue crée simplement les éléments de la liste et la deuxième vue les place réellement sur la page. Je pense que c'est assez similaire à ce qui se passe dans l' exemple ToDo sur le site backbone.js. Je pense que la convention est de vous rendre contenu dans le el. Ainsi, le el sert de lieu d'atterrissage ou de conteneur pour placer votre contenu basé sur un modèle. Backbone lie ensuite ses événements aux données de modèle qu'il contient.

Lorsque vous créez une vue , vous pouvez manipuler l'el de quatre façons en utilisant el:, tagName:, className:et id:. Si aucun de ceux-ci n'est déclaré, el par défaut est un div sans id ni classe. Il n'est pas non plus associé à la page à ce stade. Vous pouvez changer la balise en autre chose en utilisant tagName (par exemple tagName: "li", vous donnera un el de <li></li>). Vous pouvez également définir l'id et la classe de el. El ne fait toujours pas partie de votre page. La propriété el vous permet de faire une manipulation très fine du grain de l'objet el. La plupart du temps, j'utilise unel: $("someElementInThePage")qui lie en fait toute la manipulation que vous faites à el dans votre vue à la page en cours. Sinon, si vous voulez voir tout le travail que vous avez fait dans votre vue apparaître sur la page, vous devrez l'insérer / l'ajouter à la page ailleurs dans votre vue (probablement dans le rendu). J'aime penser à el comme le conteneur que toute votre vue manipule.

LeRoy
la source
Merci pour la clarification et l'exemple! Je pense que ce n'est pas toujours clair ce que devrait être le el dans certaines situations et le développeur doit en avoir une "idée". Vos explications ont certainement aidé! Une question, cependant: vous ne définissez pas un el dans votre ItemView, mais vous y accédez dans la fonction de rendu. Est-ce que ça va marcher? Existe-t-il une sorte de el par défaut si vous ne le définissez pas explicitement?
Manuel Meurer
3
Par défaut, el est une balise "div" sans identifiant ni classe. C'est un objet DOM non lié à votre DOM de page. Habituellement, je l'insère / ajoute à la page dans la fonction de rendu ou la fonction de rendu d'une vue parent.
LeRoy
Mise à jour de ma réponse avec une description des propriétés qui définissent le el.
LeRoy
5
Je suppose que mon seul problème avec la capture d'un élément préexistant avec el: $ ("# someElementID") est que votre vue en sait probablement plus qu'elle ne le devrait, ce qui rend sa réutilisation difficile. voir "Découple vue depuis DOM ..." coenraets.org/blog/2012/01/…
Scott Coates
@scoarescoare puisque vous ajoutez la propriété el lors de l'instanciation, la vue elle-même n'en sait pas plus qu'elle ne le devrait, elle reste modulaire et capable d'accepter tout $ (el) que vous voulez lui remettre. Donc, cela le rend vraiment réutilisable.
Metagrapher
6

Un peu vieux maintenant, mais j'étais également confus, et donc pour les autres personnes qui arrivent ici, ce violon pourrait aider - 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();
});
marque
la source
J'ai suivi ce modèle et j'aurais aimé ne pas l'avoir fait. Pour détruire une vue et supprimer les liaisons, la convention du backbone est view.remove (). Cela détruit $ el et le supprime du DOM, donc lorsque vous devez afficher à nouveau la vue, $ el n'existe pas.
JJ
@Mark et si j'utilise une architecture composite comme la marionnette .... ai-je encore besoin d'avoir un el de vue?
afr0
votre code de violon ne fonctionne pas, car le lien doit être jsfiddle.net/hRndn
Izzy
@Mahi Oui, vous avez raison. J'ai probablement collé un mauvais lien, désolé. Celui-ci fonctionne: jsfiddle.net/hRndn/127
Izzy
1

Vous voulez que votre 'el' fasse référence à un élément qui contient un élément enfant qui a un événement qui déclenche une modification dans votre vue. Peut être aussi large qu'une balise "body".

Joshvermaire
la source
Hmm, cela ne clarifie pas vraiment les choses non plus. La plupart du temps, les éléments qui pourraient déclencher une modification de ma vue sont à l'intérieur du modèle que la vue rend, donc avant qu'il ne soit rendu, ces éléments n'existent pas encore.
Manuel Meurer