切换树列表 Backone 和木偶中的分支

Toggle Tree List Branches in Backone and Marionette

本文关键字:分支 列表 Backone      更新时间:2023-09-26

我有一个使用Backone和木偶的嵌套树列表。 我想通过单击分支li来切换每个具有叶子的分支的视图。

当我单击树中的第二级节点以扩展它们时,存在一个错误。 单击CarTruck节点最终会关闭分支,而不是打开下一级别。 我不确定如何解决此错误。

这是我的代码的小提琴:http://jsfiddle.net/aeao3Lec/

这是我的JavaScript,数据和模板:

JavaScript:

var TheModel = Backbone.Model.extend({});
var TheCollection = Backbone.Collection.extend({
    model: TheModel,
});
var App = new Backbone.Marionette.Application();
App.addRegions({
    mainRegion: '.main-region' 
});
var TreeItemView = Backbone.Marionette.CompositeView.extend({
    initialize: function() {
        if ( this.model.get('children') ) {
            this.collection = new TheCollection( this.model.get('children') );
        }
    },
    tagName: 'ul',
    className: 'tree-list',
    template: _.template( $('#tree-template').html() ),
    serializeData: function () {
        return {
          item: this.model.toJSON()
        };
    },
    attachHtml: function(collectionView, childView) {
        collectionView.$('li:first').append(childView.el);
    },
    events: {
        'click .js-node': 'toggle'
    },
    toggle: function(e) {
        var $e = $(e.currentTarget);
        $e.find(' > .tree-list').slideToggle();
    }
});
var TreeRootView = Backbone.Marionette.CollectionView.extend({
    tagName: 'div',
    className: 'tree-root',
    childView: TreeItemView
});

var theCollection = new TheCollection(obj_data);
App.getRegion('mainRegion').show( new TreeRootView({collection: theCollection}) );

模板:

<div class="main-region">
</div>
<script type="text/template" id="tree-template">
    <li class="js-node">
        <% if (item.children) { %>
            Click to toggle -
        <% } %>
        <%- item.title %>        
    </li>
</script>

数据:

var obj_data = {
    "title": "Ford",
    "children": [
        {
            "title": "Car",
            "children": [
                {
                    "title": "Focus",
                },
                {
                    "title": "Taurus"   
                }
            ]
        },
        {
            "title": "Truck",
            "children": [
                {
                    "title": "F-150"
                }
            ]
        }
    ]
};

问题是您的视图与.js-node类有几个嵌套元素。单击父元素时,将显示子元素.js-node元素,但是当您单击其中一个元素时,事件会冒泡并重新触发父.js-node上的事件,这将关闭您刚刚单击的子项。

您可以通过调用来阻止此事件冒泡

e.stopImmediatePropagation();

我已经像这样更新了您的切换方法,它可以工作:

toggle: function(e) {
    var $e = $(e.currentTarget);
    $e.children('.tree-list').slideToggle();
    e.stopImmediatePropagation(); 
}

http://jsfiddle.net/CoryDanielson/aeao3Lec/2/

我看到的更大的问题是您的数据并不是真正的集合......是一棵树。CollectionView 实际上用于渲染模型的平面数组,而不是嵌套数组。您应该使用嵌套在彼此内部的多个 CollectionView 来呈现此数据...随着 TreeItemView 复杂性的增加,这将开始导致问题。

编辑:不,您使用的是非常适合渲染树的复合视图。