ASP.MVC EASY UI 入門之 —— Tree & ComboTree


1、常規的EASY UI的tree和comboTree代碼基本是官方的DEMO都有的,雖然很簡單,但是還是要實踐的做一次,才能更清晰的了解和使用它!先上效果圖

因為用的是code first,所以數據庫的MODEL我是這樣做的,這里面注釋了許多,是再設計表結構的時候走的彎路和一些備用的東西。

關鍵的是ID自己的唯一標示,PID是所屬的父級,無非就是一個遞歸表,也就是無極分類表。當然,這是設計的問題。

其次是顯示的文字和點擊文字后進入的一些操作。這里我只做了一個顯示的文字TEXT還有點擊文字后進入的相應鏈接。這里還可以加入顯示的圖片等內容!

Menu是數據庫的結構,但是我們的tree和ComboTree需要的數據並非數據庫里原樣的數據,所以,我們針對他們需要的數據設計了2個類。

treedata就是他需要的數據的具體形式。其中attribute就是每個節點里需要的具體內容。參考EASYUI的DEMO和文檔,我設計的這2個類。

namespace TOM.Model
{
    public class Menu
    {
        [Key]
        [Required]
        public int ID { get; set; }
        public int? PID { get; set; }
        [Required]
        [MaxLength(100)]
        public string Text { get; set; }
        [StringLength(255)]
        public string URL { get; set; }

        //[ForeignKey("PID")]
        //public virtual Menu Parent { get; set; }
        //public virtual ICollection<Menu> Children { get; set; }
    }
    [NotMapped]
    public class TreeData
    {
        //id: An identity value bind to the node.
        public string id { get; set; }
        //text: Text to be showed.
        public string text { get; set; }
        //state: The node state, 'open' or 'closed'.
        public string state { get; set; }
        //iconCls: The css class to display icon.
        public string iconCls { get; set; }
        //attributes: Custom attributes bind to the node.
        public attribute attributes { get; set; }
        //pid: string, parent id
        public string pid { get; set; }
        ////checked: Whether the node is checked. 
        ////public string @checked{get;set;}
        //[DataMember(Name = "checked")]
        //public string ischecked { get; set; }
        ////attributes: Custom attributes bind to the node.
        //public Dictionary<string, object> attributes { get; set; }
        //public List<TreeData> children { get; set; }
        ////target: Target DOM object.
    }
    [NotMapped]
    public class attribute
    {
        public string url { get; set; }
        //other data
    }
}

在EASY UI中,應該就是只有異步樹的。當然,你如果按照官方要的數據一次性全都查出來,那么就是同步樹了。

每個節點都有一個點擊事件,每次點擊Tree就會默認的Post一個id給后台(當然是異步的時候,如果已經獲取到數據了,它就不在POST)。

這里我做了2個事件。onClick事件,獲取到的是節點數據。

此外,還有一個onLoadSuccess,這個是完成異步樹的過程,它的任務是這樣的,默認我們訪問后台數據的時候,首先是'/Menu/AsyncTree',僅僅是一個URL,木有參數

[HttpPost]
public JsonResult AsyncTree(int id = 0)

默認的是給0,那么,也就是先把第一級樹節點查出來。

然后,當onLoadSuccess相應的時候,它會判斷當前的節點是否有子節點(this.state == 'closed' 有子節點的節點,其狀態是closed),如果有子節點,通過 t.tree('expandAll');就會展開這個子節點,那么如果這個子節點下的數據未被獲取到,Tree就會默認的POST當前節點的id給后台,讓后台去加載其子節點數據,相當於代替人工去click子節點。

也就是說,如果我們加入onLoadSuccess事件,並且通過this.state和 t.tree('expandAll')這2個關鍵操作,就能夠實現異步的,一次性全部加載完畢所有的樹(遞歸)。

如果我們不加入onLoadSuccess事件,也是可以的,那就是真正意義和形式上都是異步的。每次點擊節點,如果節點狀態是'closed',且,其子節點數據並沒有加載,那就Tree就會Post一個ID給后台。

            //-----------異步樹-------------------
            $('#AsyncMenu').tree({ 
                url: '/Menu/AsyncTree',
                lines: true,
                checkbox: true,
                //異步樹的點擊事件
                onClick: function (node) {
                    if (node.attributes == undefined) {
                        return;
                    }
                    if (node.attributes.url && node.attributes.url.length > 0) {
                        var src = node.attributes.url;
                        $.messager.alert('提示', '[' + src + ']!', 'info');
                    }
                },
                //異步樹全部自動展開
                onLoadSuccess: function (node, data) {
                    var t = $(this);
                    if (data) {
                        $(data).each(function (index, d) {
                            if (this.state == 'closed') {
                                t.tree('expandAll');
                            }
                        });
                    }
                }
            });

   前台的HTML這樣寫就可以

    <fieldset>
        <legend>異步樹</legend>
        <ul id="AsyncMenu"></ul>
    </fieldset>

 

此外,國人也有高手,擴展了這2個組件,使其支持,ID,PID這樣的平滑結構。也就是說,不需要遞歸,只需要把數據全部一次性的讀出來,由擴展方法來完成其節點和子節點的關系映射。節約了不少代碼,當然,它就不是異步樹了。擴展代碼如下。

var sy = sy || {};
/*
* * 擴展tree和combotree,使其支持平滑數據格式 * * @author 孫宇 * * @requires jQuery,EasyUI * */ sy.loadFilter = { loadFilter : function(data, parent) { var opt = $(this).data().tree.options; var idField, textField, parentField; if (opt.parentField) { idField = opt.idField || 'id'; textField = opt.textField || 'text'; parentField = opt.parentField || 'pid'; var i, l, treeData = [], tmpMap = []; for (i = 0, l = data.length; i < l; i++) { tmpMap[data[i][idField]] = data[i]; } for (i = 0, l = data.length; i < l; i++) { if (tmpMap[data[i][parentField]] && data[i][idField] != data[i][parentField]) { if (!tmpMap[data[i][parentField]]['children']) tmpMap[data[i][parentField]]['children'] = []; data[i]['text'] = data[i][textField]; tmpMap[data[i][parentField]]['children'].push(data[i]); } else { data[i]['text'] = data[i][textField]; treeData.push(data[i]); } } return treeData; } return data; } }; $.extend($.fn.combotree.defaults, sy.loadFilter); $.extend($.fn.tree.defaults, sy.loadFilter);

這樣一來,我們使用就相當方便了

  //----------Tree擴展方法(非異步,支持【id,pid】格式)---------------

            $('#ExtMenu').tree({
                url: '/Menu/ExtTree',
                //指定父節點字段
                parentField: 'pid',
                lines: true,
                checkbox: true,
                //點擊事件
                onClick: function (node) {
                    if (node.attributes == undefined) {
                        return;
                    }
                    if (node.attributes.url && node.attributes.url.length > 0) {
                        var src = node.attributes.url;
                        $.messager.alert('提示', '[' + src + ']!', 'info');
                    }
                }
            });
        });

 

前台HTML代碼這樣寫

    <fieldset>
        <legend>ComboTree</legend>
        <div style="margin: 10px 0">
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="getValue()">GetValue</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="setValue()">SetValue</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="disable()">Disable</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="enable()">Enable</a>
        </div>
        <select id="ComboTree" class="easyui-combotree" style="width: 200px;"
            data-options="url:'/Menu/ExtTree',required:true,parentField: 'pid',value:'1'">
        </select>
    </fieldset>

 輔助的幾個JS方法如下:

        function getValue() {
            var val = $('#ComboTree').combotree('getValue');
            $.messager.alert('提示', '[' + val + ']!', 'info');
        }
        function setValue() {
            $('#ComboTree').combotree('setValue', '2');
        }
        function disable() {
            $('#ComboTree').combotree('disable');
        }
        function enable() {
            $('#ComboTree').combotree('enable');
        }

 

后台負責直接把表數據,無腦的都一次性讀出來就完事了。

 

下面附上后台方法。

 

        #region 異步樹
        [HttpPost]
        public JsonResult AsyncTree(int id = 0)
        {
            TOM.DAL.MenuRepository d = new TOM.DAL.MenuRepository();
            List<TOM.Model.TreeData> list = new List<TOM.Model.TreeData>();
            var query = d.List().Where(m => m.PID == id);
            foreach (var item in query)
            {
                TOM.Model.TreeData temp = new TOM.Model.TreeData();
                temp.id = item.ID.ToString();
                temp.text = item.Text;
                temp.state = hasChild(item.ID) ? "closed" : "open";
                temp.iconCls = "icon-add";
                temp.attributes = new TOM.Model.attribute() { url = item.URL };
                list.Add(temp);
            }
            return Json(list);
        }
        /// <summary>
        /// 判斷是否有子節點
        /// </summary>
        /// <param name="id">父節點ID</param>
        /// <returns>Bool</returns>
        private bool hasChild(int id)
        {
            TOM.DAL.MenuRepository d = new TOM.DAL.MenuRepository();
            var query = d.List().Where(m => m.PID == id);
            return query.Count() > 0;
        }
        #endregion

        #region 擴展支持{id=0,pid=0}格式的樹
        [HttpPost]
        public JsonResult ExtTree()
        {
            TOM.DAL.MenuRepository d = new TOM.DAL.MenuRepository();
            List<TOM.Model.TreeData> list = new List<TOM.Model.TreeData>();
            var query = d.List();
            foreach (var item in query)
            {
                TOM.Model.TreeData temp = new TOM.Model.TreeData();
                temp.id = item.ID.ToString();
                temp.pid = item.PID.ToString();
                temp.text = item.Text;
                temp.iconCls = "icon-add";
                temp.attributes = new TOM.Model.attribute() { url = item.URL };
                list.Add(temp);
            }
            return Json(list);
        }
        #endregion

至於后台方法,看看就好了,本人MVC新手,寫的不好。此文章也是我備忘用的。如果能給其他人帶來方便那是最好的!

 最后附圖全部效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM