2013-05-07 107 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的模板,你可以改变它强调