2016-10-23 1 views
0

J'essaie de rendre une liste d'éléments en utilisant le modèle de soulignement. Mais ça ne montre rien.Rendu dans backbone.js avec des modèles de soulignement

J'ai essayé de créer 2 vues, une est une tâche et une est une liste de tâches, mais je suis bloqué à l'aide de modèle.

  • Que fait .render()?
  • Si j'utilise un gabarit, dois-je quand même restituer?

Je pensais que les données mapperont la variable de gabarit lorsque vous faites this.$el.html(template_var)?

<!DOCTYPE HTML> 
 
<html> 
 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Title</title> 
 
</head> 
 
<body> 
 

 

 
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<script src="http://underscorejs.org/underscore-min.js"></script> 
 
<script src="http://backbonejs.org/backbone-min.js"></script> 
 

 
     <script type="text/template" id="task_list"> 
 
      <li><%=title%></li> 
 
      <li><%=priority%></li> 
 
     </script> 
 

 
     </script> 
 

 
<script type="text/javascript"> 
 
     (function(){ 
 

 
     window.App = { 
 
      Models:{}, 
 
      Collections:{}, 
 
      Views:{} 
 
     }; 
 

 
     window.template = function(id){ 
 
      return _.template($('#' + id).html()); 
 
     } 
 
     
 

 
     App.Models.Task = Backbone.Model.extend({ 
 
       title: 'default', 
 
       priority: 1 
 
     }); 
 

 
     App.Collections.Task = Backbone.Collection.extend({ 
 
      model: App.Models.Task 
 
     }); 
 

 
     App.Views.Task = Backbone.View.extend({ 
 
      template: template('task_list'), 
 
      render(){ 
 
       var template = this.template(this.model.toJSON()); 
 
       console.log(template) 
 
       this.$el.html(template); 
 
       return this; 
 
      } 
 
     }) 
 

 
     App.Views.Tasks = Backbone.View.extend({ 
 
      tagName: 'ul', 
 
      render: function(){ 
 
       this.collection.each(this.addOne, this); 
 
       return this; 
 
      }, 
 
      addOne: function(task){ 
 
       var taskView = new App.Views.Task({ model: task}) 
 
       taskView.render(); 
 
       this.$el.append(taskView.render().el); 
 
      } 
 
     }) 
 

 
     var tasks = new App.Collections.Task([ 
 
      { 
 
        title: 'Go to store', 
 
        priority: 4 
 
       }, 
 
       { 
 
        title: 'Eat', 
 
        priority: 3 
 
       }, 
 
       { 
 
        title: 'Sleep', 
 
        priority: 4 
 
       } 
 
     ]) 
 

 
     var tasksView = new App.Views.Tasks({collection: tasks}) 
 
     $('body').html(tasksView.el) 
 

 
     })() 
 

 
</script> 
 

 
</body> 
 
</html>

Répondre

2

Vous étiez très proche, mais il y avait de petits problèmes. Backbone fait beaucoup de choses, mais une chose qu'il ne fait pas pour vous est la logique de rendu, qui est laissée à la discrétion du développeur. Donc, vous avez besoin de:

  • un modèle pour séparer le HTML de la logique JS.
  • une fonction render qui effectue le rendu en utilisant votre technique favorite, jQuery dans notre cas.

Une vue Backbone a toujours root DOM element (el) même si elle n'a pas été rendu encore, ce qui est une div par défaut si tagName n'est pas spécifiée.

donc votre point de vue de la tâche semblait quelque chose comme ceci au moment du rendu:

<div> 
    <li>Go to store</li> 
    <li>4</li> 
</div> 

J'ai changé le modèle un peu à travailler. J'ai ramené le CSS dans la section HEAD. Ceci est une norme, mais n'était pas vraiment l'un des problèmes. Les attributs par défaut d'un modèle doivent être spécifiés dans le defaults property.


fonction Définition avec le shorthand syntax comme ce qui suit est seulement disponible en ES6 (ECMAScript 2015).

render(){ 

A partir de 2015 ECMAScript (ES6), une syntaxe plus courte pour les définitions de méthode sur initializers objets est introduite. C'est un raccourci pour une fonction affectée au nom de la méthode.

Et pour le rendre compatible with most browser, vous devez utiliser:

render: function() { 

Vous avez oublié aussi d'appeler à la vue de rendre la liste.

$('body').html(tasksView.el) 

devrait être:

$('body').html(tasksView.render().el); 

Étant donné que votre code est l'intérieur d'un IIFE, vous n'avez pas besoin de faire votre application et fonctions globales avec le window, une var locale est suffisant et est une meilleure pratique de codage. .


<!DOCTYPE HTML> 
 
<html> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Title</title> 
 

 
    <!-- CSS should be in the head --> 
 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
 
</head> 
 

 
<body> 
 

 

 

 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script> 
 
    <script src="http://underscorejs.org/underscore.js"></script> 
 
    <script src="http://backbonejs.org/backbone.js"></script> 
 

 
    <script type="text/template" id="task_list"> 
 
     <%=title%> (<%=priority%>) 
 
    </script> 
 

 
    <script type="text/javascript"> 
 
     (function() { 
 

 
      var App = { 
 
       Models: {}, 
 
       Collections: {}, 
 
       Views: {} 
 
      }; 
 

 
      function template(id) { 
 
       return _.template($('#' + id).html()); 
 
      } 
 

 

 
      App.Models.Task = Backbone.Model.extend({ 
 
       defaults: { 
 
        title: 'default', 
 
        priority: 1 
 
       } 
 
      }); 
 

 
      App.Collections.Task = Backbone.Collection.extend({ 
 
       model: App.Models.Task 
 
      }); 
 

 
      App.Views.Task = Backbone.View.extend({ 
 
       template: template('task_list'), 
 
       tagName: 'li', 
 
       render: function() { 
 
        var template = this.template(this.model.toJSON()); 
 
        console.log(template) 
 
        this.$el.html(template); 
 
        return this; 
 
       } 
 
      }); 
 

 
      App.Views.Tasks = Backbone.View.extend({ 
 
       tagName: 'ul', 
 
       render: function() { 
 
        this.collection.each(this.addOne, this); 
 
        return this; 
 
       }, 
 
       addOne: function(task) { 
 
        var taskView = new App.Views.Task({ 
 
         model: task 
 
        }) 
 
        this.$el.append(taskView.render().el); 
 
       } 
 
      }); 
 

 
      var tasks = new App.Collections.Task([{ 
 
       title: 'Go to store', 
 
       priority: 4 
 
      }, { 
 
       title: 'Eat', 
 
       priority: 3 
 
      }, { 
 
       title: 'Sleep', 
 
       priority: 4 
 
      }]); 
 

 
      var tasksView = new App.Views.Tasks({ 
 
       collection: tasks 
 
      }); 
 
      $('body').html(tasksView.render().el); 
 

 
     })() 
 
    </script> 
 

 
</body> 
 

 
</html>

+0

'$ ('corps') html (tasksView.render() el.): Pourquoi je dois encore appeler à nouveau rendre ici? Est-ce que j'utilise déjà 'return this' à la fin de ma méthode de rendu? – Sandy

+0

@Sandy 'return this' est juste pour enchaîner les appels. Vous devez appeler cette ligne car 'render' ne serait pas appelé ailleurs. –

+0

étrange J'ai vu quelque chose comme sans rendu comme '$ ('body'). Html (tasksView.el);' mais j'ai oublié où – Sandy