Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone js, Update view on model change

Why my view is not getting updated?

    <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>
like image 919
Vjy Avatar asked May 16 '13 15:05

Vjy


1 Answers

You were missing a few things.

  • The row template should only render one row. The Table template repeats it in collection.each().
  • You needed to specify which model the View was tied to. Now, when the model is changed, the View "listens to" that event and fires its render action. Note that you didn't specify a model, but the collection auto creates a model for each element in the data array it's passed.
  • You were trying to use setElement for rendering the view. Rendering is as simple as passing your template's HTML to the jQuery object which is auto created by the view (this.$el in code below).
<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>
like image 131
Elias Carlston Avatar answered Oct 15 '22 21:10

Elias Carlston