web-dev-qa-db-fra.com

attacher des vues backbone.js à des éléments existants vs insérer el dans le DOM

J'implémente ma première application Backbone non didacticiel et j'ai des questions en deux à propos d'un aspect de l'utilisation de backbone.js qui ne me convient pas très bien, qui concerne l'injection du rendu d'une vue el dans le DOM par rapport à l'utilisation d'un élément existant pour el. Je soupçonne que je vais vous fournir à tous quelques "moments d'apprentissage" ici, et apprécier l'aide.

La plupart des exemples de vue de dorsale que je vois sur le Web spécifient tagName, id et/ou className, lors de la création d'une vue et créent ainsi un el qui n'est pas attaché au DOM. Ils ressemblent généralement à quelque chose comme:

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

Mais les didacticiels ne permettent pas toujours d'expliquer comment ils recommandent de placer l'élément rendu dans le DOM. Je l'ai vu de différentes manières. Donc, ma première question est: où est l'endroit approprié pour appeler la méthode de rendu d'une vue et insérer son el dans le DOM? (pas nécessairement un seul et même endroit). Je l'ai vu faire dans un routeur, dans les fonctions d'initialisation ou de rendu de la vue, ou simplement dans une fonction prête pour le document de niveau racine. ( $(function () ) . Je peux imaginer que n'importe lequel de ces travaux, mais y a-t-il une bonne manière de le faire?

Deuxièmement, je commence par un balisage HTML/filaire et convertis des portions html en modèles js correspondant aux vues de la dorsale. Plutôt que de laisser la vue rendre un élément non attaché et de fournir un point d'ancrage en html pour le coller, j'ai l'impression que c'est plus naturel, quand il n'y aura qu'un seul élément pour une vue et qu'il ne disparaîtra pas, pour utiliser un élément wrapper vide existant (souvent un div ou span) comme el lui-même. De cette façon, je n'ai pas à me soucier de trouver la place dans le document pour insérer mon el non attaché, ce qui pourrait finir par ressembler à ceci (notez la superposition supplémentaire):

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

Donc, une partie de ma deuxième question est, pour une vue essentiellement statique, y a-t-il quelque chose de mal à utiliser un élément existant du HTML de la page directement comme el de ma vue? De cette façon, je sais que c'est déjà dans le DOM, au bon endroit, et que rendre l'appel rendra immédiatement la vue sur la page. Je parviendrais à cela en passant l'élément déjà exixant au constsructor de ma vue comme "el". De cette façon, il me semble, je n'ai pas à me soucier de le coller dans le DOM (ce qui rend la question 1 en quelque sorte discutable), et appeler render mettra immédiatement à jour le DOM. Par exemple.

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

Est-ce une façon correcte de le faire pour les vues statiques sur la page? c'est-à-dire qu'il n'y a qu'un seul de ces points de vue et qu'il ne disparaîtra en aucune circonstance. Ou existe-t-il une meilleure façon? Je me rends compte qu'il peut y avoir différentes façons de faire les choses (c'est-à-dire dans un routeur, dans une vue parent, au chargement de la page, etc.) en fonction de la façon dont j'utilise une vue, mais en ce moment je regarde le chargement de la page initiale cas d'utilisation.

Merci

71
Ben Roberts

Il n'y a absolument rien de mal à l'idée d'attacher une vue à un nœud DOM existant.

Vous pouvez même simplement mettre l'el en tant que propriété sur votre vue.

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

Ce que je recommande, c'est de faire ce qui fonctionne ... La beauté de Backbone est qu'il est flexible et répondra à vos besoins.

En ce qui concerne les modèles courants, je me retrouve généralement avec une vue principale pour garder une trace des vues, puis peut-être une vue de liste et des vues d'éléments individuels.

Un autre modèle courant en ce qui concerne l'initialisation est d'avoir une sorte d'objet App pour gérer les choses ...

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

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

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

Comme je l'ai dit auparavant, il n'y a vraiment pas de mauvaise façon de faire les choses, faites simplement ce qui fonctionne. :)

N'hésitez pas à me contacter sur Twitter @ jcreamer898 si vous avez besoin d'aide, consultez également @derickbailey, c'est une sorte de gourou BB.

S'amuser!

54
jcreamer898

Vous pouvez également envoyer un objet d'élément HTML DOM dans la vue en tant que propriété "el" des options.

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')
    });
});
18
andho

Utilisez la méthode des événements délégués:

initialize: function() {
    this.delegateEvents();
}

Pour comprendre pourquoi: http://backbonejs.org/docs/backbone.html#section-138 près de "Définir les rappels, où"

0
Oleksandr Knyga

On dirait aussi que de nos jours vous pouvez youse setElement .

0
pixelearth