转载请注明作者及出处,谢谢

最近学习ASP.NET MVC 3,今天想试试jqGrid的TreeGrid模式,本以为跟着Demo一小会就能出效果,不料一直到晚上才搞定。于是把解决方案发出来以便刚接触jqGrid的兄弟参考。

需求:

显示树状结构的数据,如:部门列表。

@section head{
    <script type="text/javascript">
        $(function () {
            $('#treegrid').jqGrid({
                treeGrid: true,
                treeGridModel: 'adjacency',
                ExpandColumn: 'DeptName',
                url: '/Department/Query/',
                datatype: 'json',
                mtype: 'GET',
                colNames: ['ID', '部门名称', 'ParentID', '主管', '主管职代', '说明', 'VisibilityValue'],
                colModel: [
                { name: 'ID', index: 'ID', hidden: true, width: 1, key: true },
                { name: 'DeptName', index: 'DeptName', width: 180 },
                { name: 'ParentID', index: 'ParentID', hidden: true, width: 1 },
                { name: 'Director', index: 'Director', width: 200, align: 'left' },
                { name: 'DeputyID', index: 'DeputyID', width: 200 },
                { name: 'Summary', index: 'Summary', width: 200 },
                { name: 'VisibilityValue', index: 'VisibilityValue', hidden: true, width: 1 }
            ],
                pager: '#ptreegrid',
                height: 'auto'
            });
        })
    </script>
}

小小的补充下,我使用Razor视图引擎,所以这一部分是视图里面定义javascript的Sectiion。个人感觉,除了不能“所见即所得”之外,这个引擎比传统的ASPX要好,但具体好在什么地方呢,也说不上来,感觉而已(不要敲我:))

今天有三分之一的时间花在一个小失误上,在上面的这段代码中,datatype被我写成了dataType,结果花了n小时,一个字一个字的找出来...

使用jqGrid TreeGrid,上面这些代码就足够了,设置还有多余的,比如pager不是必须的。

再小小的一段题外话,为什么网上的很多例子在使用jqGrid时使用的mtype为"POST"?,从RESTful的角度来说不应该是"GET"吗?莫非违背RESTful原则使用MVC比较有快感?

非常重要的工作是:必须把grid.treegrid.js引用进页面,我一直以为有那个jquery.jqGrid.min.js就够了,结果还是在加入了grid.treegrid.js后才能在点击一行后进入Controller。

剩下就是Controller里面的内容了。

        public ActionResult Query(Guid? nodeid, int? n_level)
        {
            Guid? deptID = nodeid;
            int level = n_level != null ? (int)n_level + 1 : 0;
            JsonResult json = new JsonResult();
            json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            var deptMng = new DeptManager();
            var depts = deptMng.GetChild(deptID, true);
            json.Data = new
            {
                page = 1,
                total = 1,
                records = depts.Count,
                rows = (from dept in depts
                        select new
                        {
                            cell = new[] {
                                    dept.ID.ToString(),
                                    dept.DeptName,
                                    dept.ParentID != null ? dept.ParentID.ToString() : "",
                                    dept.DirectorID != null ? dept.DirectorID.ToString() : "",
                                    dept.Deputy != null ? dept.Deputy.ToString() : "",
                                    dept.Summary != null ? dept.Summary : "",
                                    dept.VisibilityValue.ToString(),
                                    level.ToString(),
                                    deptID != null ? deptID.ToString() : string.Empty,
                                    deptMng.GetChild(dept.ID,true).Count == 0 ? "true":"false",
                                    "false"
                                }
                        })
            };

            return json;
        }

说句实话,我灰常灰常喜欢”约定优于配置"这句话,很多时侯,背上的包袱总是自已加上去的,因此,为什么使用nodeid和n_level这两个参数名,我想还没有明白的就不用深究了,如果你想使用jqGrid的TreeGrid,那么你就使用这个参数列表吧。

当第一次加载视图时,nodeid和n_level均为空,因为你还没有点击树的任一节点,所以它哥俩默认为null。

当n_level为空时level为0,否则level = n_level + 1,为什么这样,后面提到。

deptMng.GetChild方法为获取指定部门ID的下一级子部门,不包括下二级。

ok,来到关键的地方了,json.Data里面放的匿名对象中,前三个成员比较简单,在能找到的所有的例子中,page和total都是1,所以我也就没有多想,名堂全在rows对象里面了:

先把你colNames和colModel里面需要的数据准备好,在本例中我使用了7个字段(真不明白,一个测试程序干嘛型那么多字段),从第八个开始有讲究:

level.ToString(),代表当前这行数据处于第level层,这也就是我为什么前面使用n_level+1的原因了,如果n_level为空的话,将要显示第0层,如果其不为空,说明当前level是n_level,将要显示的下一层level当然是n_level+1了。

第九个字段疑似存储父部门ID的,为什么是疑似呢,因为时间原因我还没有弄深入...(2011.9.11更新:可以肯定的是,这个字段就是存储父部门ID的,而且很重要的一点是,如果某节点的父ID为空的话,一定得使用null或是"null"来代替,而不能使用"",为啥呢?除非你不想使用排序(sorting)功能了)

第10个字段可以肯定的说,是存该部门是否包含子部门,记住:true代表没有子部门,false代表有子部门,似乎应该说成是否不存在子部门。

第11个字段,给个false就行了,原因不明...(2011.9.11更新: 这个字段的含义为:显示数据是否展开,true为展开,false为收起)

效果出来了。

刚开始使用jqGrid,很多东西还没有搞明白,只能依葫芦画瓢,见笑了:)

2011.9.11更新-----------------------

这里有一个可以排序的例子,这里是关于排序问题的解决方案,这两个地址在说同一件事情。

这是有关TreeGrid的完整格式的样例:

{id: "1", name: "Cash",        num: "100", debit: "400.00",  credit: "250.00",  balance: "150.00",   enbl: "1", level: "0", parent: "null", isLeaf: false, expanded: false, loaded: true}

从level属性之前,是和业务有关的数据,之后,就是jqgrid的TreeGrid所需的数据了,基本上从属性名就可以看出作用。

一直在纳闷,官方文档到底在啥地方呢...


//2011.9.26应观众要求,做一个简单的示例吧

请点这里下载

posted on 2011-02-27 21:50  think8848  阅读(7411)  评论(15编辑  收藏  举报