c'est une excellente question. L'épine dorsale est excellente en raison du manque d'hypothèses qu'elle fait, mais cela signifie que vous devez (décider comment) mettre en œuvre des choses comme ça vous-même. Après avoir regardé à travers mes propres trucs, je trouve que j'utilise (en quelque sorte) un mélange de scénario 1 et de scénario 2. Je ne pense pas qu'un quatrième scénario magique existe parce que, tout simplement, tout ce que vous faites dans les scénarios 1 et 2 doit être terminé.
Je pense qu'il serait plus facile d'expliquer comment j'aime le gérer avec un exemple. Supposons que cette simple page soit divisée en vues spécifiées:

Disons que le HTML est, après avoir été rendu, quelque chose comme ceci:
<div id="parent">
<div id="name">Person: Kevin Peel</div>
<div id="info">
First name: <span class="first_name">Kevin</span><br />
Last name: <span class="last_name">Peel</span><br />
</div>
<div>Phone Numbers:</div>
<div id="phone_numbers">
<div>#1: 123-456-7890</div>
<div>#2: 456-789-0123</div>
</div>
</div>
J'espère que la façon dont le code HTML correspond au diagramme est assez évidente.
Les ParentViewdétient 2 vues de l' enfant, InfoViewet PhoneListViewainsi que quelques divs supplémentaires, dont l' une #name, doit être fixé à un moment donné. PhoneListViewcontient ses propres vues enfants, un tableau d' PhoneViewentrées.
Passons donc à votre question réelle. Je gère l'initialisation et le rendu différemment en fonction du type de vue. Je divise mes vues en deux types, Parentvues et Childvues.
La différence entre les deux est simple, les Parentvues contiennent des vues enfants, Childcontrairement aux vues. Donc, dans mon exemple, ParentViewet PhoneListViewsont des Parentvues, tandis que InfoViewet les PhoneViewentrées sont des Childvues.
Comme je l'ai mentionné précédemment, la plus grande différence entre ces deux catégories est le moment où elles sont autorisées à effectuer le rendu. Dans un monde parfait, je veux que les Parentvues ne soient rendues qu'une seule fois. Il appartient à leur vue enfant de gérer tout nouveau rendu lorsque le ou les modèles changent. Childvues, d'autre part, je permets de restituer à tout moment dont ils ont besoin car ils n'ont pas d'autres vues en s'appuyant sur eux.
Dans un peu plus de détails, pour les Parentvues, j'aime mes initializefonctions pour faire quelques choses:
- Initialiser ma propre vue
- Rendre ma propre opinion
- Créez et initialisez toutes les vues enfant.
- Attribuez à chaque vue enfant un élément dans ma vue (par exemple, la
InfoViewserait attribuée #info).
L'étape 1 est assez explicite.
L'étape 2, le rendu, est effectuée de sorte que tous les éléments sur lesquels les vues enfants s'appuient existent déjà avant que j'essaie de les affecter. Ce faisant, je sais que tous les enfants eventsseront correctement définis et je peux restituer leurs blocs autant de fois que je le souhaite sans me soucier de devoir déléguer quoi que ce soit. Je n'ai pas vraiment renderd'opinion d'enfant ici, je leur permets de le faire dans le leur initialization.
Les étapes 3 et 4 sont en fait gérées en même temps que je passe ellors de la création de la vue enfant. J'aime passer un élément ici car je pense que le parent devrait déterminer où à son avis l'enfant est autorisé à mettre son contenu.
Pour le rendu, j'essaie de le garder assez simple pour les Parentvues. Je veux que la renderfonction ne fasse rien de plus que rendre la vue parent. Aucune délégation d'événement, aucun rendu de vues enfants, rien. Juste un simple rendu.
Parfois, cela ne fonctionne pas toujours. Par exemple, dans mon exemple ci-dessus, l' #nameélément devra être mis à jour chaque fois que le nom dans le modèle change. Cependant, ce bloc fait partie du ParentViewmodèle et n'est pas géré par une Childvue dédiée , donc je contourne cela. Je vais créer une sorte de subRenderfonction qui ne remplace que le contenu de l' #nameélément, et je n'aurai pas à jeter la totalité de l' #parentélément. Cela peut sembler être un hack, mais j'ai vraiment trouvé que cela fonctionnait mieux que d'avoir à se soucier de restituer l'ensemble du DOM et de rattacher les éléments et autres. Si je voulais vraiment le nettoyer, je créerais une nouvelle Childvue (similaire à la InfoView) qui gérerait le #namebloc.
Maintenant, pour les Childvues, le initializationest assez similaire aux Parentvues, juste sans la création d'autres Childvues. Alors:
- Initialiser ma vue
- Le programme d'installation lie l'écoute de tout changement au modèle qui m'importe
- Rendre ma vue
Childle rendu de vue est également très simple, il suffit de rendre et de définir le contenu de mon el. Encore une fois, pas de problème avec la délégation ou quelque chose comme ça.
Voici un exemple de code de ce à quoi mon ParentViewpeut ressembler:
var ParentView = Backbone.View.extend({
el: "#parent",
initialize: function() {
// Step 1, (init) I want to know anytime the name changes
this.model.bind("change:first_name", this.subRender, this);
this.model.bind("change:last_name", this.subRender, this);
// Step 2, render my own view
this.render();
// Step 3/4, create the children and assign elements
this.infoView = new InfoView({el: "#info", model: this.model});
this.phoneListView = new PhoneListView({el: "#phone_numbers", model: this.model});
},
render: function() {
// Render my template
this.$el.html(this.template());
// Render the name
this.subRender();
},
subRender: function() {
// Set our name block and only our name block
$("#name").html("Person: " + this.model.first_name + " " + this.model.last_name);
}
});
Vous pouvez voir ma mise en œuvre subRenderici. En ayant des modifications liées à subRenderau lieu de render, je n'ai pas à me soucier de dynamiter et de reconstruire le bloc entier.
Voici un exemple de code pour le InfoViewbloc:
var InfoView = Backbone.View.extend({
initialize: function() {
// I want to re-render on changes
this.model.bind("change", this.render, this);
// Render
this.render();
},
render: function() {
// Just render my template
this.$el.html(this.template());
}
});
Les liens sont la partie importante ici. En me liant à mon modèle, je n'ai jamais à me soucier de renderm'appeler manuellement . Si le modèle change, ce bloc se restitue sans affecter les autres vues.
Le PhoneListViewsera similaire au ParentView, vous aurez juste besoin d'un peu plus de logique dans vos fonctions initializationet renderpour gérer les collections. La façon dont vous gérez la collection dépend vraiment de vous, mais vous devrez au moins écouter les événements de la collection et décider de la façon dont vous souhaitez effectuer le rendu (ajouter / supprimer ou simplement restituer le bloc entier). Personnellement, j'aime ajouter de nouvelles vues et supprimer les anciennes, pas restituer la vue entière.
Le PhoneViewsera presque identique au InfoView, n'écoutant que les changements de modèle qui lui tiennent à cœur.
J'espère que cela a aidé un peu, s'il vous plaît laissez-moi savoir si quelque chose prête à confusion ou n'est pas assez détaillé.