Backbone js append替换html而不是追加元素

时间:2015-11-03 13:42:39

标签: javascript jquery html backbone.js

我是backbone.js的初学者。我开始创建一个小型todo应用程序,其中包含Addy Yosmani的“Backbone基础知识”中的示例。我有以下示例代码。我为每个项目使用了一个视图,我有一个列表视图,其中我渲染每个项目并将其附加到列表中,但不是追加它而是替换整个项目。我尝试使用调试器,并且元素在第一次循环运行后保留第一个待办事项但在第二次运行时元素被替换而不是追加。我无法找到解决方案。

代码

<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Hello World in Backbone.js</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
    </head>

    <body>

        <div id="my-container">
        </div>

        <div class="container container-fluid" id="container" style="margin-top:5px;">
        </div>

        <script type="text/template" id="item-template">
            <div class="post-panel" style="margin-top:5px;">
                <div class="panel-default panel-heading post-title">
                    <%= title %>
                </div>
                <div class="panel-default panel-body post-content">
                    <%= content %>
                </div>
            </div>
        </script>

        <script>
         var Todo = Backbone.Model.extend();

         var TodoItemView = Backbone.View.extend({

             todo_tpl: _.template($('#item-template').html()),

             el: $('#container'),

             render: function() {
                 this.$el.html(this.todo_tpl(this.model.attributes));
                 return this;
             },
         });

         var TodoListView = Backbone.View.extend({

             el: $('#my-container'),

             render: function() {

                 posts = [
                     {'title': 'sample title 1' , 'content': 'sample content 1'},
                     {'title': 'sample title 2' , 'content': 'sample content 2'},
                     {'title': 'sample title 3' , 'content': 'sample content 3'},
                     {'title': 'sample title 4' , 'content': 'sample content 4'},
                 ];

                 for (i=0; i < posts.length; i++) {
                     var todo1 = new Todo(posts[i]);
                     var todo1_view = new TodoItemView({model: todo1});
                     this.$el.append(todo1_view.render().el);
                 }
                 return this;
             },

         });


         var todo1 = new Todo({"title" : "sample title" , "content" : "sample content"});
         var todo1_view = new TodoItemView({model: todo1});
         var todo_list_view = new TodoListView();
         todo_list_view.render()
             //         todo1_view.render();

        </script>
    </body>

</html>

2 个答案:

答案 0 :(得分:1)

在您的代码中,目前您为每个帖子调用TodoItemView,并在TodoItemView内调用:

this.$el.html(this.todo_tpl(this.model.attributes));

这就是为什么它只显示 last 帖子(它不断更换帖子)。由于有多个TodoItemView,您需要更改此行以使用append

this.$el.append(this.todo_tpl(this.model.attributes));

Fiddle

答案 1 :(得分:1)

来自Backbone.View.el

  

this.el可以从DOM选择器字符串或Element中解析出来;   否则,它将从视图tagNameclassNameid创建   和attributes属性。 如果没有设置,this.el是一个空div,   这通常很好。也可以传入el参考   view的构造函数。

所以你可以简单地添加一个选项设置:

className: 'container container-fluid'

或者您还希望保留style="margin-top:5px;"

attributes: {
    className: 'container container-fluid',
    style: 'margin-top:5px;'
}

下面以tagName方式演示,您可以看到属性方式here

         var Todo = Backbone.Model.extend();

         var TodoItemView = Backbone.View.extend({

           todo_tpl: _.template($('#item-template').html()),

           // Give the created element classes
           className: 'container container-fluid',

           // Backbone default creates an empty div if you don't specifiy
           // tagName: 'div',

           render: function() {
             this.$el.html(this.todo_tpl(this.model.attributes));
             return this;
           },
         });

         var TodoListView = Backbone.View.extend({

           el: $('#my-container'),

           render: function() {

             posts = [{
               'title': 'sample title 1',
               'content': 'sample content 1'
             }, {
               'title': 'sample title 2',
               'content': 'sample content 2'
             }, {
               'title': 'sample title 3',
               'content': 'sample content 3'
             }, {
               'title': 'sample title 4',
               'content': 'sample content 4'
             }, ];

             for (i = 0; i < posts.length; i++) {
               var todo1 = new Todo(posts[i]);
               var todo1_view = new TodoItemView({
                 model: todo1
               });
               this.$el.append(todo1_view.render().el);
             }
             return this;
           },

         });


         var todo1 = new Todo({
           "title": "sample title",
           "content": "sample content"
         });
         var todo1_view = new TodoItemView({
           model: todo1
         });
         var todo_list_view = new TodoListView();
         todo_list_view.render()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>

<div id="my-container">
</div>

<div class="container container-fluid" id="container" style="margin-top:5px;">
</div>

<script type="text/template" id="item-template">
  <div class="post-panel" style="margin-top:5px;">
    <div class="panel-default panel-heading post-title">
      <%=title %>
    </div>
    <div class="panel-default panel-body post-content">
      <%=content %>
    </div>
  </div>
</script>