javascript 骨干 js,更新模型更改视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16591359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 05:14:37  来源:igfitidea点击:

backbone js, Update view on model change

javascriptbackbone.js

提问by Vjy

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>

回答by Elias Carlston

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).
  • 行模板应该只呈现一行。Table 模板在 collection.each() 中重复了它。
  • 您需要指定视图绑定到哪个模型。现在,当模型更改时,视图“监听”该事件并触发其渲染操作。请注意,您没有指定模型,但集合会自动为它传递的数据数组中的每个元素创建一个模型。
  • 您试图使用 setElement 来呈现视图。渲染就像将模板的 HTML 传递给视图自动创建的 jQuery 对象一样简单(下面代码中的 this.$el)。
<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>

回答by HungryCoder

You need to bind your view on model's change. I'm assuming you want to update RowView when a row is updated. I've rewritten your RowView. This will now listen to your model's change.

您需要在模型更改上绑定您的视图。我假设您想在更新一行时更新 RowView。我已经重写了你的RowView. 这现在将听取您的模型的变化。

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() {

         }
     });

回答by Tommi Komulainen

Because your TableView.initialize is accessing this.modelbut you're passing it a collectioninstead?

因为您的 TableView.initialize 正在访问this.model但您正在传递它collection