2013-05-16 12 views
10

Perché la visualizzazione non viene aggiornata?10 backbone js, vista di aggiornamento sul cambio di modello

<html> 

    <script src="./jquery.js"></script> 
    <script src="./underscore-min.js"></script> 
    <script src="./backbone.js"></script> 

    <style> 
     table,td {border:1px solid #000;} 
    </style> 

    <body> 
    </body> 

    <script> 

    var rowTemplate="<tr><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td><td class='name'><%= name %></td><td class='age'><%= age %></td></tr>"; 

    /** View representing a table */ 
    var TableView = Backbone.View.extend({ 

     tagName: 'table', 

     initialize : function() { 
      _.bindAll(this,'render','renderOne'); 
      if(this.model) { 
       this.model.on('change',this.render,this); 
       console.log(this.model); 
      } 
     }, 

     render: function() { 
      this.collection.each(this.renderOne); 
      return this; 
     }, 

     renderOne : function(model) { 
      var row=new RowView({model:model}); 
      this.$el.append(row.render().$el); 
      return this; 
     } 
    }); 

    /** View representing a row of that table */ 
    var RowView = Backbone.View.extend({ 
     events: { 
      "click .age": function() {console.log(this.model.get("name"));} 
     }, 

     render: function() { 
      var html=_.template(rowTemplate,this.model.toJSON()); 
      this.setElement($(html)); 
      return this; 
     }, 

     update : function() { 

     } 
    }); 

    var data = [ 
     {'name': 'Oli', 'age': 25}, 
     {'name': 'Oli', 'age': 25}, 

     ]; 

    /** Collection of models to draw */ 
    var peopleCollection = new Backbone.Collection(data); 
    var tableView = new TableView({collection: peopleCollection}); 
    $("body").append(tableView.render().$el); 

    console.log(peopleCollection.models[0].set({'name': 'VJY', 'age': 25})); 
    console.log(peopleCollection.models[0]); 

    </script> 

    </html> 

risposta

16

Ti mancavano alcune cose.

  • Il modello di riga deve eseguire solo una riga. Il modello Tabella lo ripete in collection.each().
  • È necessario specificare a quale modello è stata collegata la vista. Ora, quando il modello viene modificato, la vista "ascolta" quell'evento e attiva la sua azione di rendering. Si noti che non è stato specificato un modello, ma la raccolta automatica crea un modello per ciascun elemento nell'array di dati che ha passato.
  • Si stava tentando di utilizzare setElement per il rendering della vista. Il rendering è semplice come passare il codice HTML del modello all'oggetto jQuery che viene creato automaticamente dalla vista (questo. $ El nel codice seguente).
<html> 
    <script src="./jquery.js"></script> 
    <script src="./underscore.js"></script> 
    <script src="./backbone.js"></script> 
    <style> 
     table, 
     td { 
      border: 1px solid #000; 
     } 
    </style> 
    <body></body> 
    <script> 
     var rowTemplate = "<tr><td class='name'><%= name %></td><td class='age'><%= age %></td></tr>"; 

     var data = [ 
       { 
        'name': 'Bert', 
        'age' : 6 
       }, { 
        'name': 'Ernie', 
        'age' : 7 
       } 
      ]; 

     /** Collection of models to draw */ 
     var peopleCollection = new Backbone.Collection(data); 

     /** View representing a table */ 
     var TableView = Backbone.View.extend({ 
       tagName: 'table', 
       initialize: function() { 
        _.bindAll(this, 'render', 'renderOne'); 
        if (this.model) { 
         this.model.on('change', this.render, this); 
         console.log(this.model); 
        } 
       }, 
       render: function() { 
        this.collection.each(this.renderOne); 
        return this; 
       }, 
       renderOne: function (model) { 
        var row = new RowView({ 
          model: model 
         }); 
        this.$el.append(row.render().$el); 
        return this; 
       } 
      }); 

     /** View representing a row of that table */ 
     var RowView = Backbone.View.extend({ 
       events: { 
        "click .age": function() { 
         console.log(this.model.get("name")); 
        } 
       }, 
       initialize: function() { 
        this.model.on('change', this.render, this); 
       }, 
       model: peopleCollection.models, 
       render: function() { 
        var html = _.template(rowTemplate, this.model.toJSON()); 
        this.$el.html(html); 
        return this; 
       }, 
      }); 

     var tableView = new TableView({ 
       collection: peopleCollection 
      }); 
     $("body").append(tableView.render().$el); 

     console.log(peopleCollection.models[0].set({ 
      'name': 'Statler', 
      'age' : 100 
     })); 
     console.log(peopleCollection.models[0]); 
    </script> 
</html> 
+4

Penso che sia meglio usare 'listenTo' invece di' on' now - https://stackoverflow.com/questions/16823746/backbone-js-listento-vs-on –

+0

Bel manuale per capire Views! Grazie! –

1

Perché il vostro TableView.initialize sta accedendo this.model ma si sta passando un collection invece?

+0

Come aggiornare allora? – Vjy

2

È necessario associare la visualizzazione al cambiamento del modello. Suppongo che tu voglia aggiornare RowView quando una riga viene aggiornata. Ho riscritto il tuo RowView. Questo ora ascolterà il cambiamento del tuo modello.

var RowView = Backbone.View.extend({ 
     events: { 
      "click .age": function() {console.log(this.model.get("name"));} 
     }, 
     initialize: function(){ 
      this.model.on('change', this.render, this); 
     }, 
     render: function() { 
      var html=_.template(rowTemplate,this.model.toJSON()); 
      this.setElement($(html)); 
      return this; 
     }, 

     update : function() { 

     } 
    });