2015-11-03 66 views
0

我是backbone.js的初學者。我開始用Addy Yosmani的「Backbone fundamentals」的例子創建一個小型待辦事項應用程序。我有如下代碼示例。我爲每個項目使用了一個視圖,並且我有一個列表視圖,其中我呈現每個項目並將其附加到列表中,而不是附加它來替換整個項目。我嘗試了一個調試器,並且元素在第一次循環運行後保持第一次待辦事項,但在第二次運行時元素被替換而不是追加。我找不出解決方案。Backbone js append替換html而不是追加元素

代碼

<!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

所有ItemView控件都指向同一個元素'$( '#集裝箱')'的。所以你的代碼會覆蓋'$('#container')'中的內容,並將它附加到'$('#my-container')'。 – fuyushimoya

+0

@fuyushimoya謝謝。我只是評論它,我得到渲染的元素。我怎樣才能創建四個容器類的元素? – xtreak

+0

@fuyushimoya既然你說它附加了新創建的內容以及div'my-container',爲什麼它會被替換? – xtreak

回答

1

Backbone.View.el

this.el可以從一個DOM選擇字符串或元素來解決; 否則將從視圖的tagName,className,idattributes屬性創建。 如果沒有設置,this.el是一個空格, 這往往很好。 el引用也可以傳遞給視圖的構造函數。

所以,你可以簡單地增加一個選項設置:

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>

+0

非常感謝。這就是我在評論中提到的整個事情。 – xtreak

+1

我還在[jsfiddle](http://jsfiddle.net/6nnd13t0/3/)上添加了另一種使用'attributes'的方法,你可以看到更適合你,因爲你的原始div有這樣的風格, [Backbone.View.attributes]的引用(http://backbonejs.org/#View-attributes)。 :) – fuyushimoya

+0

謝謝:)我也是Javascript的初學者。我不知道再次追加同一個DOM元素將不會追加它。更多學習:)我在當天追加了一個字符串,現在我想知道追加同一個DOM元素和將它作爲字符串追加到append方法之間的區別。 – xtreak

1

在您的代碼,您目前正在呼籲TodoItemView每個帖子,裏面TodoItemView你說:

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

這是它只會顯示最後的原因(不斷更換帖子)。由於有多個TodoItemView的,你需要改變這一行使用append

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

Fiddle

+0

謝謝。但是,最後不返回'this'返回對象,然後該元素被追加到'TodoListView' el。那麼我應該刪除列表視圖?我不明白這一點。爲什麼交換'append'和'html'不起作用? – xtreak

相關問題