2013-05-08 43 views
0

我做的極其相似,在這篇文章中所描述的樹狀結構的東西:選項傳遞從的CollectionView遞歸CompositeView中

http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/

的想法是有集合視圖中根節點的集合( TreeRoot),其中每個根節點也有一個遞歸合成視圖(TreeView)。一的jsfiddle顯示簡單的工作示例從aricle樹結構可以在這裏找到:

http://jsfiddle.net/hoffmanc/NH9J6/

我想修改的例子使一些選項可以傳遞給每個樹視圖,無論它在樹結構中。這是我的(只有非常輕微的修改)的jsfiddle:

http://jsfiddle.net/QL4AE/1/

在我的變形例的JS代碼:

// The recursive tree view 
var TreeView = Backbone.Marionette.CompositeView.extend({ 
    template: "#node-template", 

    tagName: "li", 

    initialize: function(){ 
     // grab the child collection from the parent model 
     // so that we can render the collection as children 
     // of this parent node 
     this.collection = this.model.nodes; 
     console.log(this.options.msg); // undefined! 
    }, 

    appendHtml: function(cv, iv){ 
     cv.$("ul:first").append(iv.el); 
    }, 
    onRender: function() { 
     if(_.isUndefined(this.collection)){ 
      this.$("ul:first").remove(); 
     } 
    } 
}); 

// The tree's root: a simple collection view that renders 
// a recursive tree structure for each item in the collection 
var TreeRoot = Backbone.Marionette.CollectionView.extend({ 
    tagName: "ul", 
    itemView: TreeView 
}); 



// ---------------------------------------------------------------- 
// Below this line is normal stuff... models, templates, data, etc. 
// ---------------------------------------------------------------- 
treeData = [ 
    { 
    nodeName: "top level 1", 
    nodes: [ 
     { 
     nodeName: "2nd level, item 1", 
     nodes: [ 
      { nodeName: "3rd level, item 1" }, 
      { nodeName: "3rd level, item 2" }, 
      { nodeName: "3rd level, item 3" } 
     ] 
     }, 
     { 
     nodeName: "2nd level, item 2", 
     nodes: [ 
      { nodeName: "3rd level, item 4" }, 
      { 
       nodeName: "3rd level, item 5", 
       nodes: [ 
        { nodeName: "4th level, item 1" }, 
        { nodeName: "4th level, item 2" }, 
        { nodeName: "4th level, item 3" } 
       ] 
      }, 
      { nodeName: "3rd level, item 6" } 
     ] 
     } 
    ] 
    }, 
    { 
    nodeName: "top level 2", 
    nodes: [ 
     { 
     nodeName: "2nd level, item 3", 
     nodes: [ 
      { nodeName: "3rd level, item 7" }, 
      { nodeName: "3rd level, item 8" }, 
      { nodeName: "3rd level, item 9" } 
     ] 
     }, 
     { 
     nodeName: "2nd level, item 4", 
     nodes: [ 
      { nodeName: "3rd level, item 10" }, 
      { nodeName: "3rd level, item 11" }, 
      { nodeName: "3rd level, item 12" } 
     ] 
     } 
    ] 
    } 

]; 


TreeNode = Backbone.Model.extend({ 
    initialize: function(){ 
     var nodes = this.get("nodes"); 
     if (nodes){ 
      this.nodes = new TreeNodeCollection(nodes); 
      this.unset("nodes"); 
     } 
    }   
}); 

TreeNodeCollection = Backbone.Collection.extend({ 
    model: TreeNode 
}); 

var tree = new TreeNodeCollection(treeData); 
var treeView = new TreeRoot({ 
    collection: tree, 
    itemViewOptions: {msg: 'hi'} 
}); 

正如你所看到的,我試圖用itemViewOptions選項傳遞,但是當TreeView初始化時,它不在那裏。我假設這是因爲只有TreeRoot獲得itemViewOptions。

我的問題是:如何將選項從TreeRoot傳遞給TreeView?

謝謝!

+0

見我回答這個問題。 http://stackoverflow.com/a/16427755/693799 – 2013-05-08 17:00:46

+0

傳遞選項只是簡單的使用Backbone,但我不知道如何做到這一點,特別是在這種情況下,有一個遞歸的複合視圖... – stank345 2013-05-08 17:13:33

回答

0

由於UI需求(需要在表格中放置樹),我們最終選擇了一個稍微不同的實現。我們使用名爲treetable的jQuery插件在表內創建樹。在下面的示例代碼中,集合視圖只是一組項目視圖(項目視圖直接附加到DOM)。每個有孩子的節點爲他們創建一個新的集合視圖。 ItemView el需要追加的jQuery對象傳遞給每個ItemView。

的Javascript

var NodeView = Backbone.Marionette.ItemView.extend({ 
    tagName: "tr", 
    template: "#node-template", 

    onRender: function() { 

     var parent = this.model; 
     var children = parent.nodes; 
     var table = this.options.table; 

     if (!table) { 
      throw "No table element passed. Nowhere to append rows!"; 
     } 

     table.append(this.el); 

     if (children !== undefined) { 
      // create and render new collection view for children nodes 
      var childrenView = new TreeRoot({ 
       collection: children, 
       parent: parent, 
       table: table 
      }); 
      childrenView.render(); 
     } 
    } 
}); 


var TreeRoot = Backbone.Marionette.CollectionView.extend({ 
    itemView: NodeView, 

    itemViewOptions: function() { 
     return { 
      table: this.options.table 
     } 
    }, 

    appendHtml: function(collectionView, itemView, index){ 

     /* 
     * Set custom attributes needed by TreeTable jQuery plugin 
     */ 

     var model = itemView.model; 
     $(itemView.el).attr("data-tt-id", model.get("nodeName")); 

     var parent = collectionView.options.parent; 
     if (parent !== undefined) { 
      $(itemView.el).attr("data-tt-parent-id", parent.get("nodeName")); 
     } 
    } 

}); 



// ---------------------------------------------------------------- 
// Below this line is normal stuff... models, templates, data, etc. 
// ---------------------------------------------------------------- 
treeData = [ 
    { 
    nodeName: "top level 1", 
    nodes: [ 
     { 
     nodeName: "2nd level, item 1", 
     nodes: [ 
      { nodeName: "3rd level, item 1" }, 
      { nodeName: "3rd level, item 2" }, 
      { nodeName: "3rd level, item 3" } 
     ] 
     }, 
     { 
     nodeName: "2nd level, item 2", 
     nodes: [ 
      { nodeName: "3rd level, item 4" }, 
      { 
       nodeName: "3rd level, item 5", 
       nodes: [ 
        { nodeName: "4th level, item 1" }, 
        { nodeName: "4th level, item 2" }, 
        { nodeName: "4th level, item 3" } 
       ] 
      }, 
      { nodeName: "3rd level, item 6" } 
     ] 
     } 
    ] 
    }, 
    { 
    nodeName: "top level 2", 
    nodes: [ 
     { 
     nodeName: "2nd level, item 3", 
     nodes: [ 
      { nodeName: "3rd level, item 7" }, 
      { nodeName: "3rd level, item 8" }, 
      { nodeName: "3rd level, item 9" } 
     ] 
     }, 
     { 
     nodeName: "2nd level, item 4", 
     nodes: [ 
      { nodeName: "3rd level, item 10" }, 
      { nodeName: "3rd level, item 11" }, 
      { nodeName: "3rd level, item 12" } 
     ] 
     } 
    ] 
    } 

]; 


TreeNode = Backbone.Model.extend({ 
    initialize: function(){ 
     var nodes = this.get("nodes"); 
     if (nodes){ 
      this.nodes = new TreeNodeCollection(nodes); 
      this.unset("nodes"); 
     } 
    }   
}); 

TreeNodeCollection = Backbone.Collection.extend({ 
    model: TreeNode 
}); 

var tree = new TreeNodeCollection(treeData); 

var table = $('#tree'); 

var treeView = new TreeRoot({ 
    collection: tree, 
    table: table 
}); 

treeView.render(); 

table.treetable({ expandable: true }); 

HTML

<html> 
    <head> 
     <link href="https://raw.github.com/ludo/jquery-treetable/master/stylesheets/jquery.treetable.css" rel="stylesheet" type="text/css" /> 
     <link rel="stylesheet" href="https://raw.github.com/ludo/jquery-treetable/master/stylesheets/jquery.treetable.theme.default.css"> 
    </head> 
    <body> 
     <script src="https://raw.github.com/documentcloud/underscore/master/underscore-min.js"></script> 
     <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
     <script src="https://raw.github.com/documentcloud/backbone/master/backbone-min.js"></script> 
     <script src="https://raw.github.com/derickbailey/backbone.marionette/master/lib/backbone.marionette.js"></script> 
     <script src="https://raw.github.com/ludo/jquery-treetable/master/javascripts/src/jquery.treetable.js"></script> 

     <script id="node-template" type="text/template"> 
      <td><%= nodeName %></td> 
     </script> 

     <table id="tree"> 
      <thead> 
       <tr> 
        <th>Name</th> 
       </tr> 
      </thead> 
      <tbody> 
      </tbody> 
     </table> 

     <script src="tree.js"></script> 
    </body> 
</html>