您的位置:首页 > 产品设计 > UI/UE

operamasks-ui2.0 +MVC4.0+EF5.0实战之四 部门管理功能及网格控件(datagrid)

2013-02-09 11:25 411 查看
  前几篇侧重点还是在布局,下面,主角出场,网格控件的地位和意义已无需再说,内容也比较多,预计得分几篇才能说完,本文是一些基础的东西,但不乏需要注意的地方。

  对于MIS系统来说,公司的组织架构是一个基础的功能(网站系统则没有所谓的部门及成员,而侧重于以个体为单位的会员),也即通常所说的部门。与前面说的菜单类似,通常也是采取自关联形成树形结构。为了方便维护,设计上采取左侧树,右侧网格的方式,先上效果图,以便有个直观的印象。

View Code

using Common.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Model.Json
{
public class DataGridRow
{
public string id { get; set; }
public List<string> cell { get; set; }
}
public class DataGrid<T>:Object
{
public int total { get; set; }
public List<T> rows { get; set; }
public static DataGrid<T> ConvertFromList(List<T> list)
{
DataGrid<T> data = new DataGrid<T>();

if (list != null)
{
data.total = list.Count;
data.rows = list;
}
else
{
data.total = 0;
}

return data;
}

public static DataGrid<T> GetAllData(IQueryable<T> query)
{
DataGrid<T> data = new DataGrid<T>();

if (query != null)
{
data.total = query.Count();
data.rows = query.ToList();
}
else
{
data.total = 0;
}

return data;
}
public static DataGrid<T> GetPageData(IQueryable<T> query,PageView pageView)
{
DataGrid<T> data = new DataGrid<T>();
if (query != null)
{
data.total = query.Count();
if (pageView != null)
{

if (pageView.PageSize > 0 && pageView.PageIndex >= 0)
{

query = query.Skip(pageView.PageIndex * pageView.PageSize).Take(pageView.PageSize);
}

}
data.rows = query.ToList();
}
else
{
data.total = 0;
}

return data;
}

}

}


  前台还有一个部门树点击的事件处理,就是就部门的id传给后侧的网格:

function TreeNodeClick(nodeData,event)
{
$('#datagrid').omGrid({ extraData: $.extend({ id: nodeData.id }, defaultSort) });
}


  事实上,你看到的最终的结果,中间还是经历了一些曲折……

  首先一个问题跟本节内容关系不大,但是本节中暴露出来了,就是实战三中,点击功能菜单后,在右侧业务区域中动态添加tab页,嵌入iframe,相关的js如下  

  function TreeNodeClick(node, event)
{
$("#tabs").omTabs('add', {
title: node.text,
content: '<iframe scrolling="yes" frameborder="0"  src=' + node.url + ' style="width:100%;height:100%;"></iframe>',
closable: true,
tabId:node.id
});
}


  咋看上去是没问题,添加了tab页,当时运行也没发现问题,加了内容后就出问题了,高度!高度不能自动适配,只显示大概几百像素,没有填充整个tab页,即使设置了style="width:100%;height:100%;也没用,而在easyui中就没这问题,直接可以实现完美的完全填充效果,查找资料,反复试验,最终采取下面这种方式勉强达到效果:

content: '<iframe id="frame" onload="$(this).height($(this).contents().find(' + "tabs" + ').height()-55)" scrolling="yes"  frameborder="0"  src=' + node.url + ' style="width:100%;height:100%"></iframe>'


  即使用js在iframe加载完成后,动态获取tab标签页的高度然后减去55px,设置为iframe的高度,至于为什么设置为55,一是tab标签头部自身25px,另外30是一些margin、border占用的,目测和试验55效果最好,未在多浏览器多显示器下测试,可能还有问题。若你有更好的解决方式,欢迎留言说明,先行谢过。

  第二个问题是关于服务器端排序问题,datagrid的colModel属性,可以设置各列的排序方式,客户端、服务器端或者自定义js函数,如果是采用服务器端排序,即设置 sort: 'serverSide'。另外,我后台分页,对IQureyable对象使用Skip方法,该方法要求必须有orderBy子句,从业务角度考虑,通常也需要在datagrid首次加载的时候设置一个默认排序字段和排序方式(asc或desc)。查看了官方示例和说明,datagrid自身属性没有排序相关内容,而是在其基础了外挂了一个排序插件,点击列标题的时候会向后台发送sortBy和sortDir。初始化的时候,则没有提供对外设置关于排序的方法和属性,因此,只能放到extraData属性中。结果问题就来了,调试时候发现,服务器端排序不起作用,发现前台传给后台的排序参数,始终是初始化中设置的Name和asc,点击列头根本不起作用。无奈之下只能查看om源码,幸好源码是开放的且注释比较多,找到了omGrid的_populate方法,大概在11040行,发现了问题所在,合并参数的时候,用初始化的参数,把排序两字段覆盖了,源代码如下: 

var param =$.extend(true,{},this._extraData,op.extraData,{
start : limit * (nowPage - 1),
limit: limit,
_time_stamp_ : new Date().getTime()
});


  问题是找到了,但是om没有提供任何关于排序的方法或属性,用于控制点击列头来排序这个过程,全部内置了。无奈之下,只有修改源代码,把排序两个字段传了过去  

var param =$.extend(true,{},this._extraData,op.extraData,{
start : limit * (nowPage - 1),
limit: limit,
sortBy: this._extraData.sortBy,
sortDir: this._extraData.sortDir,
_time_stamp_ : new Date().getTime()
});


  小改动,改完后服务器端排序总算正常了,理论上对其他地方也没影响,应该不会因为改动带来新的问题。要设置初始加载后的默认排序字段,自身属性不提供,只能通过extraData这里加上,若自定义名字,不跟sortBy和sortDir重名,则后台方法就要分别处理,还要区分两种情况,若重名,则又会被初始参数覆盖,左右为难,这应该算一个BUG吧?

  本篇到此为止,这就是网格控件,实现了取数、展现、排序和分页,下节介绍增、删、改、查。

  最后,祝园子里各位新年快乐!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: