【EasyUi DataGrid】动态加载列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenyanmoting/article/details/47170573

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

一、操作流程

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


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


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


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

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

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

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

       当然,更换了组合框中的投标商后,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的总结已经写完,有失误的地方,欢迎指正~

猜你喜欢

转载自blog.csdn.net/chenyanmoting/article/details/47170573