Backbone.js: appeler rendu () à partir de l'initialisation de la vue: fonction

Je souhaite que mon point de vue se réalise quand il est créé pour la première fois, alors this.render(); Dans la fonction initialize: comme cela (un code supprimé):

 var MyView = Backbone.View.extend({ el: $("#mydiv"), initialize: function() { this.render(); } ... 

Dans la fonction de render: je bouge ensuite une collection enfant et j'ajoute les vues rendues de chaque élément enfant:

 render: function() { this.model.somecollection.forEach(function(c) { var view = new ChildView({ model: c }); this.el.append(view.render().el); //***** }); return this; }, 

Le problème que je pose est que la référence à this dans la fonction de rendu (marquée par des astérisques) est définie sur la window plutôt que sur l'objet MyView , et cela provoque une erreur.

Je suppose que this.render(); rendu incorrectement (actuellement this.render(); ). Comment puis-je faire cela pour que le contexte actuel soit préservé?

Enregistrez this dehors de la boucle for.

 var that = this; 

this n'est pas transporté dans la boucle si vous utilisez _.each() .

Dans Javascript, chaque fois que vous entrez un nouveau contexte de fonction, la valeur de this a probablement changé. Tout ce que vous devez faire est de stocker la valeur de this avant d'entrer dans la fonction:

 render: function() { var self = this; this.model.somecollection.forEach(function(c) { var view = new ChildView({ model: c }); self.el.append(view.render().el); //***** }); return this; }, 

C'est ainsi que nous l'utilisons ici,

De cette façon, le rendu est toujours invoqué lors de l'initialisation.

 ContactView = Backbone.View.extend({ initialize: function(){ this.render(); }, render: function(){ // we use underscsore templating, this just gives a chunk of html var template = _.template( $("#search_template").html(), {} ); // and we load that template html into the Backbone "el" this.el.html( template ); } }); 

Nous donnons le 'el' à la vue lorsque nous créons la vue, et la fonction de rendu insère html dans cet élément.

 var contact_view = new ContactView({ el: $("#contact-list") }); 

Dans le contexte de la fonction anonyme, il s'agit de la portée globale. Vous devez le conserver explicitement si vous souhaitez utiliser le code comme vous l'avez écrit. En supposant que vous avez jquery dans votre page: $ .proxy peut être utilisé:

 This.model.somecollection.forEach ($. Proxy (function (c) {
 Var view = new ChildView ({model: c});  
         This.el.append (view.render (). El);
  },ce));

Alternativement, le trait de soulignement possède une fonction _.bind qui fonctionne de manière similaire. De plus, si vous définissez une variable locale et attribuez-la à cette fonction anonyme, vous pouvez l'utiliser à la place de cette fonction anonyme.

Si somecollection est un Backbone.Collection, vous devriez pouvoir dire:

this.model.somecollection.each(..., this);

Le dernier paramètre est le contexte à utiliser dans la fonction.