2013-05-07 99 views
2

我嘗試使用下面的backbone.js進行嵌套導航是我的代碼。多級ul li backbone.js

JSON數據:

[ 
{"id":1,"name":"one","parent_id":0}, 
{"id":2,"name":"two","parent_id":0}, 
{"id":3,"name":"three","parent_id":0}, 
{"id":4,"name":"four","parent_id":0}, 
{"id":5,"name":"five","parent_id":0}, 
{"id":6,"name":"one","parent_id":2}, 
{"id":7,"name":"two","parent_id":2}, 
{"id":8,"name":"three","parent_id":2}, 
{"id":9,"name":"four","parent_id":2}, 
{"id":10,"name":"five","parent_id":2}, 
] 

HTML:

<ul> 
    <li><a href="#">one</a></li> 
    <li><a href="#">two</a> 
     <ul> 
      <li><a href="#">one</a></li> 
      <li><a href="#">two</a></li> 
      <li><a href="#">three</a></li> 
      <li><a href="#">four</a></li> 
      <li><a href="#">five</a></li> 
     </ul> 
    </li> 
    <li><a href="#">three</a></li> 
    <li><a href="#">four</a></li> 
    <li><a href="#">five</a></li> 
</ul> 

和Backbonejs代碼在這裏:

var MenuList = Backbone.View.extend({ 
    tagName: 'ul', 
    id: 'menu-trial-task', 
    initialize: function() { 
      this.collection = new ItemCollection(); 
      this.collection.on('sync', this.render, this); 
      this.collection.fetch();  
    }, 
    render: function() { 
     _.each(this.collection.models, function(item) { 
      this.$el.append(new MenuItem({model:item}).render().el); 
     }, this); 
    $('nav').html(this.$el);  
     return this; 
    } 
}); 

var MenuItem = Backbone.View.extend({ 
    tagName: 'li', 
    initialize: function() { 
     this.template = _.template($('#munu_itemt_view').html()); 
    }, 
    render: function() { 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; 
     } 
});  
var menuList = new MenuList(); 

,其結果是:

<ul> 
    <li><a href="#">one</a></li> 
    <li><a href="#">two</a></li> 
    <li><a href="#">three</a></li> 
    <li><a href="#">four</a></li> 
    <li><a href="#">five</a></li> 
    <li><a href="#">one</a></li> 
    <li><a href="#">two</a></li> 
    <li><a href="#">three</a></li> 
    <li><a href="#">four</a></li> 
    <li><a href="#">five</a></li>  
</ul> 

你可以看到這不是必需的結果。

我也嘗試underscore.js但失敗。有沒有什麼好的和簡單的方法來做到這一點?

+0

什麼是你的問題,或者至少,你的代碼出了什麼問題?你也應該使用模板,下劃線js有一個默認的模板引擎。 – 2013-05-07 11:24:58

+0

你在生成最終的html有問題嗎? – 2013-05-07 11:28:24

+0

是的! @Waqar Alamgir我也在我的問題中添加了結果。 – 2013-05-07 11:29:35

回答

1

嵌套視圖嘗試,我會建議使用模板

var data = [ 
    {"id":1,"name":"one","parent_id":0}, 
    {"id":2,"name":"two","parent_id":0}, 
    {"id":3,"name":"three","parent_id":0}, 
    {"id":4,"name":"four","parent_id":0}, 
    {"id":5,"name":"five","parent_id":0}, 
    {"id":6,"name":"one","parent_id":2}, 
    {"id":7,"name":"two","parent_id":2}, 
    {"id":8,"name":"three","parent_id":2}, 
    {"id":9,"name":"four","parent_id":2}, 
    {"id":10,"name":"five","parent_id":2}, 
] 

var NestedView = Backbone.View.extend({ 
    render: function(){ 
    this.$el.html("<ul id='ul-0'></ul>") 
    this.collection.each(function(model){ this.renderElement(model) }, this) 
    }, 

    renderElement: function(model){ 
    var ul = this.getParentUl(model); 
    this.appendElement(ul, model); 
    }, 

    getParentUl: function(model) { 
    var ul = this.$el.find("#ul-" + model.get("parent_id")); 
    if(ul.length == 0) { 
     this.appendListInElement(model); 
     ul = this.$el.find("#ul-" + model.get("parent_id")); 
    } 

    return ul; 
    }, 

    appendListInElement: function(model){ 
    var li = this.$el.find("#li-" + model.get("parent_id")); 
    li.after("<ul id='ul-" + model.get("parent_id") + "'></ul>"); 
    }, 

    appendElement: function(ul, model){ 
    ul.append("<li id='li-" + model.get("id") + "'>" + model.get("name") + "</li>"); 
    } 
}); 

var elements = new Backbone.Collection(data); 
var nestedView = new NestedView({ el: "#wrapper", collection: elements }); 
nestedView.render(); 


<div id="wrapper"></div> 

下面是完整的代碼,以下劃線模板

<!DOCTYPE html> 
<html> 
<head> 
    <title>Backbone</title> 
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
    <script type="text/javascript" src="http://underscorejs.org/underscore.js"></script> 
    <script type="text/javascript" src="http://backbonejs.org/backbone.js"></script> 

    <script type="text/template" id="parent-template"> 
     <ul id='ul-<%= parent_id %>'></ul> 
    </script> 
    <script type="text/template" id="child-template"> 
     <li id="li-<%= id %>"><%= name %></li> 
    </script> 

    <script type="text/javascript"> 

    var compiledParent = _.template($('#parent-template').html()); 
    var compiledChild = _.template($('#child-template').html()); 

    var data = [ 
     {"id":1,"name":"one","parent_id":0}, 
     {"id":2,"name":"two","parent_id":0}, 
     {"id":3,"name":"three","parent_id":0}, 
     {"id":4,"name":"four","parent_id":0}, 
     {"id":5,"name":"five","parent_id":0}, 
     {"id":6,"name":"one","parent_id":2}, 
     {"id":7,"name":"two","parent_id":2}, 
     {"id":8,"name":"three","parent_id":2}, 
     {"id":9,"name":"four","parent_id":2}, 
     {"id":10,"name":"five","parent_id":2}, 
    ]; 

    var NestedView = Backbone.View.extend({ 
     render: function(){ 
     this.$el.html(compiledParent({parent_id : '0'})); 
     this.collection.each(function(model){ this.renderElement(model) }, this) 
     }, 

     renderElement: function(model){ 
     var ul = this.getParentUl(model); 
     this.appendElement(ul, model); 
     }, 

     getParentUl: function(model) { 
     var ul = this.$el.find("#ul-" + model.get("parent_id")); 
     if(ul.length == 0) { 
      this.appendListInElement(model); 
      ul = this.$el.find("#ul-" + model.get("parent_id")); 
     } 

     return ul; 
     }, 

     appendListInElement: function(model){ 
     var li = this.$el.find("#li-" + model.get("parent_id")); 
     li.after(compiledParent({parent_id : model.get("parent_id")})); 
     }, 

     appendElement: function(ul, model){ 
     ul.append(compiledChild({id:model.get("id") , name:model.get("name")})); 
     } 
    }); 

    $(document).ready(function() 
    { 
     var elements = new Backbone.Collection(data); 
     var nestedView = new NestedView({ el: "#wrapper", collection: elements }); 
     nestedView.render(); 
    }); 
    </script> 
</head> 
<body> 
    <div id="wrapper"> 
    </div> 
</body> 
</html> 
+0

我試圖實現你的答案,但沒有顯示,並沒有顯示任何錯誤。 它只是顯示'

    ' – 2013-05-07 12:16:23

    +0

    你是怎麼稱呼你的js的?

    應該被認爲是頂部 – 2013-05-07 12:57:03

    +0

    是的,這是在頂部和結果是'

      ' – 2013-05-07 14:18:20

      1

      這個怎麼樣,我覺得這是更好地建立自己的JSON作爲你會想要菜單。

      你也不應該忘記把你的嵌套ul也放在li之內,否則它是無效的。

      它不會像我說過的那樣使用模板,但我認爲它足夠完成這項工作。 它只需要jquery的工作。

      var menu = [ 
          {name:"one"}, 
          { 
           name:"two", 
           nodes: [ 
            {name:"one"}, 
            {name:"two"}, 
            {name:"three"}, 
            {name:"four"}, 
            {name:"five"} 
           ] 
          }, 
          {name:"three"}, 
          {name:"four"}, 
          {name:"five"} 
      ]; 
      
      function createMenu(menuItem) 
      { 
          var list = $("<ul>"); 
          $.each (menuItem, function(indexInArray, currentItem){ 
           var li = $("<li>").html(currentItem.name); 
           if (currentItem.nodes) 
            li.append(createMenu(currentItem.nodes)); 
           list.append(li); 
          }); 
          return list; 
      } 
      
      $("body").append(createMenu(menu)); 
      

      小提琴: http://jsfiddle.net/3gjkZ/2/

      +0

      我玩這個答案,但看起來真棒:)讓我來實現這個。 – 2013-05-07 12:20:39

      +0

      很高興喜歡它,我刪除了下劃線的依賴關係,你現在只需要jQuery;) 確保接受答案,如果它幫助你了! – 2013-05-07 12:55:18

      +0

      我正在使用此功能,並面臨一個問題:(此功能解除了骨幹視圖事件的綁定。 – 2013-05-08 20:06:50

      1

      變化呈現這樣的:

      render: function() { 
          this.$el.html(this.template(items : this.model.toJSON())); 
          return this; 
      } 
      

      和teplate這樣的:

      <ul> 
          <li><a href="#">${name}</a> 
           <ul> {each items} 
            <li><a href="#">${name}</a></li> 
           </ul> 
          </li> 
      </ul> 
      

      使用jQuery的模板,你可以改變它強調