bootstrap ace treeview组件的使用

本文详细介绍了Ace框架中TreeView组件的使用方法,包括数据结构配置、事件监听等关键步骤,并提供了一个可运行的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        ace是基于bootstrap的一个优秀样式实现.其中菜单树TreeView是一个相当好用的一个目录树结构。不过因为文档不全,坑还很多。整合的使用的时候还是花费了一番心血的。

        简单的就不说了,大家把样例代码拿到本地,一个基本的菜单树就可以跑。下面提一下,抽取代码整理成自己应用时碰到的一些问题。

        首先是显示问题:

        TreeView的节点是动态绑定的,所以原先是很容易使用的。只要绑定好要显示树的html节点即可,例如:

        <div id="tree1"></div>

        就要准备相关的目录树的数据,数据结构如下:

        var data = {

               “菜单标识”:{

                      name:"要显示的菜单名",

                      type:"item/folder",//item表示端节点,folder表示还有其他儿子节点

                      。。。..这里可以放置其他节点内容,这里挺重要,下面说道如何控制其事件处理时会提到

                      additionalParameters:{//如果有子节点,则需要即type为folder时需要

                                children:{//固定和additionalParameters配套的

                                          “子菜单标识”:{

                                                     name:"子菜单显示的名称",

                                                     type:"还是子菜单的类型item/folder",

                                                     ....其他属性名

                                          }

                                }

                      }

              }

       }

       这样就整理出对应的目录树的结构了。

       下面还要如此包装一下这个数据:

       var DataSourceTree = function(options) {
        this._data = options.data;
        this._delay = options.delay;
    }


    DataSourceTree.prototype.data = function(options, callback) {
        var self = this;
        var $data = null;


        if (! ("name" in options) && !("type" in options)) {
            $data = this._data;
            //the root tree
            callback({
                data: $data
            });
            return;
        } else if ("type" in options && options.type == "folder") {
            if ("additionalParameters" in options && "children" in options.additionalParameters) $data = options.additionalParameters.children;
            else $data = {}


        }


        if ($data != null)


        setTimeout(function() {
            callback({
                data: $data
            });
        },
        parseInt(Math.random() * 500) + 200);
  }
    
  var showData = new DataSourceTree({
        data: resultData
    });


  好,要显示的数据,就封装在showData 中了,然后进行初始化,如下:

 $('#tree1').ace_tree({
        dataSource: showData ,
        multiSelect: false,
        loadingHTML: '<div class="tree-loading"><i class="icon-refresh icon-spin blue"></i></div>',
        'open-icon': 'icon-minus',
        'close-icon': 'icon-plus',
        'selectable': true,
        'selected-icon': 'icon-ok',
        'unselected-icon': 'icon-remove'
    });


   这样这棵树,就可以显示了。但是上面的数据,通过样例,还是可以很容易获取到其用法的,简单的单步跟踪一下即可。

   下面最坑的就是如何获取这棵树上的点击事件。这个表面上没有例子,很难找到对应的方法和内容的,经过我漫长努力,还是找到了。核心关键就是fuelux.tree.min.js文件。

这个是底层声明treeview的基本框架代码:

(function(a, c) {
    var b = function(e, d) {
        this.$element = a(e);
        this.options = a.extend({},
        a.fn.tree.defaults, d);
        this.$element.on("click", ".tree-item", a.proxy(function(f) {
            this.selectItem(f.currentTarget)
        },
        this));
        this.$element.on("click", ".tree-folder-header", a.proxy(function(f) {
            this.selectFolder(f.currentTarget)
        },
        this));
        this.render()
    };
    b.prototype = {
        constructor: b,
        render: function() {
            this.populate(this.$element)
        },
        populate: function(f) {
            var e = this;
            var d = f.parent().find(".tree-loader:eq(0)");
            d.show();
            this.options.dataSource.data(f.data(),
            function(g) {
                d.hide();
                a.each(g.data,
                function(h, j) {
                    var i;
                    if (j.type === "folder") {
                        i = e.$element.find(".tree-folder:eq(0)").clone().show();
                        i.find(".tree-folder-name").html(j.name);
                        i.find(".tree-loader").html(e.options.loadingHTML);
                        var k = i.find(".tree-folder-header");
                        k.data(j);
                        if ("icon-class" in j) {
                            k.find('[class*="icon-"]').addClass(j["icon-class"])
                        }
                    } else {
                        if (j.type === "item") {
                            i = e.$element.find(".tree-item:eq(0)").clone().show();
                            i.find(".tree-item-name").html(j.name);
                            i.data(j);
                            if ("additionalParameters" in j && "item-selected" in j.additionalParameters && j.additionalParameters["item-selected"] == true) {
                                i.addClass("tree-selected");
                                i.find("i").removeClass(e.options["unselected-icon"]).addClass(e.options["selected-icon"])
                            }
                        }
                    }
                    if (f.hasClass("tree-folder-header")) {
                        f.parent().find(".tree-folder-content:eq(0)").append(i)
                    } else {
                        f.append(i)
                    }
                });
                e.$element.trigger("loaded")
            })
        },
        selectItem: function(e) {
            if (this.options.selectable == false) {
                return
            }
            var d = a(e);
            var g = this.$element.find(".tree-selected");
            var f = [];
            if (this.options.multiSelect) {
                a.each(g,
                function(i, j) {
                    var h = a(j);
                    if (h[0] !== d[0]) {
                        f.push(a(j).data())
                    }
                })
            } else {
                if (g[0] !== d[0]) {
                    g.removeClass("tree-selected").find("i").removeClass(this.options["selected-icon"]).addClass(this.options["unselected-icon"]);
                    f.push(d.data())
                }
            }
            if (d.hasClass("tree-selected")) {
                d.removeClass("tree-selected");
                d.find("i").removeClass(this.options["selected-icon"]).addClass(this.options["unselected-icon"])
            } else {
                d.addClass("tree-selected");
                d.find("i").removeClass(this.options["unselected-icon"]).addClass(this.options["selected-icon"]);
                if (this.options.multiSelect) {
                    f.push(d.data())
                }
            }
            if (f.length) {
                this.$element.trigger("selected", {
                    info: f
                })
            }
        },
        selectFolder: function(e) {
            var d = a(e);
            var f = d.parent();
            if (d.find("." + this.options["close-icon"]).length) {
                if (f.find(".tree-folder-content").children().length) {
                    f.find(".tree-folder-content:eq(0)").show()
                } else {
                    this.populate(d)
                }
                f.find("." + this.options["close-icon"] + ":eq(0)").removeClass(this.options["close-icon"]).addClass(this.options["open-icon"]);
                this.$element.trigger("opened", d.data())
            } else {
                if (this.options.cacheItems) {
                    f.find(".tree-folder-content:eq(0)").hide()
                } else {
                    f.find(".tree-folder-content:eq(0)").empty()
                }
                f.find("." + this.options["open-icon"] + ":eq(0)").removeClass(this.options["open-icon"]).addClass(this.options["close-icon"]);
                this.$element.trigger("closed", d.data())
            }
        },
        selectedItems: function() {
            var e = this.$element.find(".tree-selected");
            var d = [];
            a.each(e,
            function(f, g) {
                d.push(a(g).data())
            });
            return d
        }
    };
    a.fn.tree = function(e, g) {
        var f;
        var d = this.each(function() {
            var j = a(this);
            var i = j.data("tree");
            var h = typeof e === "object" && e;
            if (!i) {
                j.data("tree", (i = new b(this, h)))
            }
            if (typeof e === "string") {
                f = i[e](g)
            }
        });
        return (f === c) ? d: f
    };
    a.fn.tree.defaults = {
        multiSelect: false,
        loadingHTML: "<div>Loading...</div>",
        cacheItems: true
    };
    a.fn.tree.Constructor = b
})(window.jQuery);

这段代码是加密后,反向格式化的,所以里面的变量都是abc之类的,但是不要紧,大家关注一下上面的onclick函数调用,对调用了selectItem,继续跟踪

selectItem最后又调用了this.$element.trigger("selected", {
                    info: f
                })

这就是底牌的关键了,this.$element就是当前我们绑定树的那个html节点的jquery包装器,然后,selected不解释,大家自己看看jquery的trigger方法。后面的f就是当前被你选中节点的对应的你的数据结构,注意上面数据结构中,自己定义的除name和type外的其他数据,都可以在这里获取到。所以这就简单了。

$("#tree1").bind('selected',function(a,b,c,d){
  alert(0);
  });


搞定,至于详细参数,自己跟踪吧。

使用例子其实在众联breeze中的工具部分大量的用到。众联Breeze是一个不错的开发框架,很全,前后端都有,里面的工具是一个集成的在线编辑工具,很有意思,有情趣的朋友可以上去翻翻。

另外,在相关资源中也可以找到treeviewgadget,这个是我们用gadget将整个怪兽封装了一层,拿起即用方便的多。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值