【EasyUi DataGrid】动态加载列

时间:2022-08-16 16:18:15

       动态加载列可以说是一个从无到有的过程,如果只是网页上的DataGrid实现那就太无味了,有趣的在这里,这个页面上连带着一大堆的数据库表的查询修改,尤其是做着做着发现数据表设计有缺陷,需要的数据竟然只有出口没有入口,想想也是醉了,对业务不熟悉真心的杀不起。其实吧这个蛮好玩的,就像玩捉迷藏藏得那个人叫做nothing,再后来我又遇到了Multiple-births(多胞胎),一个页面上涉及到了六七张数据库表,里边的字段名虽然不一样,可它就是达到了百分之七八十的相似度!来吧,先看看页面上的操作流程

一、操作流程

       1.页面一加载是这个样子的

【EasyUi DataGrid】动态加载列

       2.输入招标编号后,一点击确定是这个样子的

【EasyUi DataGrid】动态加载列

       这里已经把DataGrid动态加载出来了,如果你想问为什么不在页面加载前就定义了DataGrid呢?好吧,没有招标编号这个参数,它只会报错、报错、报错!或者提前先定义好几套DataGrid的js,在输入了招标编号后根据招标编号动态调用?在网上查阅到很多人都是这样做的,不过我得定义多少套呢,况且我还不知道它会有多少列,每列叫什么。把上边的图划分一下,大家再看看

【EasyUi DataGrid】动态加载列

       有了1,才有2和3,有了2才有了3中的4,这样说好像很傻的样子,可以略过,goon

       3.选择投标商后,即可显示我们需要的信息

【EasyUi DataGrid】动态加载列

       评委还没有对该投标商评过分,所以“专家评分Id”、评分项“暗标”等是空的。上图只是它很平静的表面,它的真实面目如下图,其中没有算计投标商以及联系起投标商和DataGrid二者用到的表。D表的显示数据可以有多个列,这里只用了一条演示

【EasyUi DataGrid】动态加载列

       4.填入分数后,可以用咱们上篇博客写到的对DataGrid的编辑功能,提交到后台了

【EasyUi DataGrid】动态加载列

       当然,更换了组合框中的投标商后,DataGrid中的信息也跟着变动

【EasyUi DataGrid】动态加载列

二、代码实现

       1.Html页面上的代码很简单

<body>
<div style="margin-top: auto; margin-left: 50px;">
<div class="easyui-panel" title="评分信息" style="width: 1142px;">

<div style="margin: 10px 20px; float: left">
@* 1.加载搜索框 *@
请输入招标编号:@Html.TextBox("BidRecordId")
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-search',plain:true" onclick="Ok()">确定</a>
</div>

<div id="dropDownList" style="margin: 12px 50px; display: none;">
请选择投标商:
<input id="companyName" class="easyui-combobox" name="companyName" value="--请选择--" data-option="
method:'get',
panelWidth:350,
panelHeight:'auto',
formatter:formatItem
">
</div>
</div>
</div>
@*主体内容部分*@
<div id="contentAreas" style="margin-top: 10px; margin-left: 50px; width: 1142px; display: none">

<div class="easyui-panel" title="评分项管理" style="width: 1142px;">
@* 加载按钮 *@
<div id="btnAreas" style="margin-bottom: 5px; margin-top: 10px;">
<div id="tb" style="width: auto; height: auto">
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-save',plain:true" onclick="save()">保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-undo',plain:true" onclick="reject()">撤销</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-search',plain:true" onclick="getChanges()">获取修改行</a>
</div>
</div>

<div>
<table id="dg" class="easyui-datagrid" style="width: 1140px; height: 400px; padding-left: 200px;">
</table>
</div>
</div>
</div>
</body>
       2.js中的实现代码比较多,精简了一些,下边是我用到的主要函数
var editIndex = undefined; //用来获取编辑的行号var bidRecordId; //定义一个变量,用来保存招标编号var columnsAll = new Array(); //定义一个新的列集合,用来保存返回的数据//显示隐藏的信息function Ok() {    if ($("#BidRecordId").val() == "") {        alert("请输入招标编号!");        $("#BidRecordId").select();    } else {        //显示组合框        document.getElementById("dropDownList").style.display = "";        //获取搜索框中的内容        bidRecordId = document.getElementById("BidRecordId").value;                //2.动态加载组合框中的数据,写法有误,返回函数功能不能实现        $('#companyName').combobox({            url: '/BidManager/GetTUserByZUser?BidRecordId=' + bidRecordId,            valueField: 'Value',            textField: 'Text'        });        //显示主体内容页        document.getElementById("contentAreas").style.display = "";            //动态加载表头中的数据,ajax调用后台方法        load_dg();                //当组合框中的文本更换时,获取组合框中所对应的Id值,并加载表格中的数据        $('#companyName').combobox({            onSelect: function () {                bidRecorderId = $('#companyName').combobox('getValue').trim(); //获取组合框中文本所对应的id值                //TODO:添加一个弹出框,在有未保存信息的情况下,提醒用户是否保存                if (editIndex != undefined) {                    alert("您修改的数据将不被保存!");                                   }                editIndex = undefined; //确保在组合框中的文本更换时,对应的datagrid的编辑功能可用                //id值为空,则只传递招标编号,否则把“招标编号”和“投标商id”拼接成字符串                if (bidRecorderId != "[object HTMLInputElement]") {                    var key = bidRecordId + "," + bidRecorderId;                } else {                    var key = bidRecordId                }                //2.加载数据并显示DataGrid中的值                $.ajax({                    url: '/BidManager/GetSpecialistByZBid?Key=' + key,                    success: function (data) {                        //加载完数据后,切割评分项                         var array = new Array;                        //将加载到的值,重新赋值传给datagrid                        for (var i = 0; i < data.length; i++) {                            var obj = new Object();                            obj.SpecialistId = data[i].SpecialistId;                            obj.ItemScoreId = data[i].ItemScoreId;                            obj.SpecialistName = data[i].SpecialistName;                            obj.Score = data[i].Score; //或者用obj['Scores']=data[i].Score;                            obj.BidRecorderId = bidRecorderId;                            //评分的分数不为空,则对评分项分数进行切割                            if (data[i].ItemScores != null) {                                //将整体的评分项,切割成单个的评分项                                var ItemScores = data[i].ItemScores; //获取所有评分项的评分Id及分数                                var scoreEvery = new Array(); //定义一个数组来接收每个评分Id及其分数                                scoreEvery = ItemScores.split("##"); //将切割得到的各个评分项Id及其分数,放入定义好的数组中                                //将单个的评分项id与分数值切割开                                for (var j = 0; j < scoreEvery.length; j++) {                                    var score = new Array(); //定义一个数组,用来装载评分项分数切割后的值                                    score = scoreEvery[j].split("#"); //将一个评分项分数的id与分数值分隔开                                        obj[score[0].toLowerCase()] = score[1]; //把切割好的分数值对(id+分数)添加到数组中                                 }                            };                            //将对象装载到数组中                            array.push(obj);                        }                        $('#dg').datagrid('loadData', array);                    }                })            }        })    };}//动态加载表头中的数据,ajax调用后台方法function load_dg() {    $.post('/BidManager/ShowBidProperties?BidRecordId=' + bidRecordId, function (jsonObj) {        //如果返回的数据不为空,则添加遍历该数据集合        if (jsonObj.length > 0) {            for (var i = 0; i < jsonObj.length; i++) {                //把返回的数据封装到一个对象中                var col = {}                col["title"] = jsonObj[i].FieldText;                col["field"] = jsonObj[i].FieldValue;                col["editor"] = jsonObj[i].Editor;                 col["width"] = 150;                col["align"] = 'center'                //col["hidden"] = jsonObj[i].Hidden;                //把这个对象添加到列集合中                columnsAll.push(col);            }            //重新加载表格            $('#dg').datagrid({                height: 500,                singleSelect: true,                url: '',                fit: true,                singleSelect: true,                toolbar: '#tb',                method: 'get',                columns: [columnsAll],                onClickRow: onClickRow, //单击事件                            }).datagrid("reload");        }        else {            $.messager.alert('提示信息', '没有可用数据,请联系管理员!', 'warning');        }    }, "JSON");}//保存按钮,多条数据一起提交function save() {    if (endEditing()) {        //获取更新更改的行的集合        row = $("#dg").datagrid('getChanges');        //DataGrid的更该行为不为0        if (row.length) {            var array = new Array;            for (var i = 0; i < row.length; i++) {                var obj = new Object();                obj.SpecialistId = row[i].SpecialistId;                obj.ItemScoreId = row[i].ItemScoreId;                obj.SpecialistName = row[i].SpecialistName;                obj.Score = row[i].Score;                obj.BidRecorderId = row[i].BidRecorderId;                //拼接所有评分项的值                var valueAll = "";                for (var h = 3; h < columnsAll.length - 1; h++) {                    var title = columnsAll[h].field.toUpperCase(); //获取这列的列Id                    var field = row[i][columnsAll[h].field]; //获取单元格的值                    //获取所有评分项的id与值                    if (valueAll == "" || valueAll == null) {                        valueAll += title + "#" + field;                    } else {                        valueAll += "##" + title + "#" + field;                    }                }                obj.ItemScores = valueAll;                array.push(obj);            }            $.ajax(                {                    type: 'POST',                    url: "/BidManager/UpdateOrAddItemScore",                    data: { arrayList: JSON.stringify(array), },                    success: function (data) {                        if (data != "") {                            $.messager.alert('提示', '保存成功!');                            $('#dg').datagrid('reload');    // 重新载入当前页面数据                          }                        else {                            $.messager.alert('提示信息', '保存失败,请联系管理员!', 'warning');                        }                    }                });        }        else  //如果没有修改数据,则提醒用户        {            $.messager.alert('提示信息', '您还没有修改信息!', 'warning');        }    }    editIndex = undefined;}
       3.Controller中的代码就是查询并定义DataGrid的表头,其中有四列是固定的,即A、B、C、E四个表对应的表头是固定的,A、B两表对应的列在实际中会被隐藏,D表对应的列根据实际评分项的数量自动扩充或缩减。因为每一列的属性都是固定的,所以我新建了一个专门的ViewModel类用来管理列属性(这个ViewModel放在服务端)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.Serialization;namespace LFBidSystem.ViewModel{    [DataContract]    public class TableHeaderViewModel    {        /*表头描述            * 1.FieldValue:键值            * 2.FieldText:显示名称            * 3.Hidden:是否隐藏        */        [DataMember]        public string FieldValue;        [DataMember]        public string FieldText;        [DataMember]        public bool Hidden;        [DataMember]        public string Editor;    }}
       Controller中加载表头的方法如下

    string bidRecordId;
#region 加载表头信息 + 王静娜 2015-5-28 10:31:54
public ActionResult ShowBidProperties()
{
//表头实体集合
List<TableHeaderViewModel> listHeaderVM = new List<TableHeaderViewModel>();

//隐藏的表头列“评分项得分编号”
TableHeaderViewModel judgeHeader1Hide = new TableHeaderViewModel
{
FieldValue = "SpecialistId",
FieldText = "专家Id",
Hidden = true
};
listHeaderVM.Add(judgeHeader1Hide);

//隐藏的表头列“评分项得分编号”
TableHeaderViewModel judgeHeader2Hide = new TableHeaderViewModel
{
FieldValue = "ItemScoreId",
FieldText = "专家评分Id",
Hidden = true
};
listHeaderVM.Add(judgeHeader2Hide);


//第一列“评委”
TableHeaderViewModel judgeHeaderFirst = new TableHeaderViewModel
{
FieldValue = "SpecialistName",
FieldText = "评委",
Hidden = false
};
listHeaderVM.Add(judgeHeaderFirst);


//第二列及倒数第二列之前,各评分项遍历
//获取页面上的招标编号,并转化成Guid格式的数据类型
bidRecordId = Request.Params["BidRecordId"];
Guid recordId = new Guid(bidRecordId);

//根据招标编号,获取所对应的所有评分项信息,评分名称作为表头
List<BidJudgeViewModel> listBidJudge = iBidJudgeService.GetBidJudge(recordId);

foreach (var item in listBidJudge)
{
TableHeaderViewModel JudgeHeader = new TableHeaderViewModel();

JudgeHeader.FieldValue = item.JudgeId.ToString();
JudgeHeader.FieldText = item.JudgeItemName;
JudgeHeader.Hidden = false;
JudgeHeader.Editor = "text";
listHeaderVM.Add(JudgeHeader);
}

//最后一列“总分”
TableHeaderViewModel judgeHeaderLast = new TableHeaderViewModel
{
FieldValue = "Score",
FieldText = "总分",
Editor = "text",
Hidden = false
};
listHeaderVM.Add(judgeHeaderLast);

//将封装的表头信息返回给前台
return Json(listHeaderVM, JsonRequestBehavior.AllowGet);
}
#endregion

        这样动态加载列基本上就实现了,里边比较麻烦的是把Controller中查询到的表头信息显示到页面上,这部分在js中实现。由于数据库表字段中有一列(D表)用到了值拼接,所以循环切割拼接在所难免,从而也导致了列显示更加复杂一些,都做出来后整个感觉都好了。。。

       三篇DataGrid的总结已经写完,有失误的地方,欢迎指正~