·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 通过实例学习Fireasy开发(中篇)

通过实例学习Fireasy开发(中篇)

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

通过实例学习Fireasy开发(中篇)

本文目录

通过实例学习Fireasy开发(上篇)

通过实例学习Fireasy开发(中篇)

通过实例学习Fireasy开发(下篇)

通过实例学习Fireasy开发(补充/示例代码下载)

上篇我们介绍了进行Fireasy开发的前期准备,接下来,我们将通过两个小功能来演示怎么进行业务开发。

一、部门列表页面

部门是树型结构,Fireasy采用了00010001这样的编码来支持树结构实体的快速开发。

1、 修改Dept类(使用Dept_Ex分部类文件),在类名称上添加EntityTreeMappingAttribute特性,InnerSign指定存储00010001编码的属性,在Dept类里是使用No作为这一标识的。

    //如果要启用实体验证,请使用以下特性,并在 DeptMetadata 中定义验证特性。    [MetadataType(typeof(DeptMetadata))]     [EntityTreeMapping(InnerSign="No")]    public partial class Dept    {    }

编码每一层默认使用4位编码,如果要改成2位,可以将SignLength属性设置为2。

2、 修改Dept类,使它实现ITreeNode<>接口,目的是返回json的时候可以使用子节点等这样的属性,后面会介绍。

    //如果要启用实体验证,请使用以下特性,并在 DeptMetadata 中定义验证特性。    [MetadataType(typeof(DeptMetadata))]     [EntityTreeMapping(InnerSign="No")]    public partial class Dept: ITreeNode<Dept>    {        public System.Collections.Generic.List<Dept> Children { get; set; }        System.Collections.IList ITreeNode.Children        {            get { return Children; }            set { Children = (System.Collections.Generic.List<Dept>)value; }        }        public bool HasChildren { get; set; }        public bool IsLoaded { get; set; }    }

3、 打开DeptList.aspx文件,将datagrid替换成treegrid,修改loadData函数如下:

        //加载数据        function loadData() {            $('#dg').treegrid({                url: 'DeptList.ajx/GetDepts',                fit: true,//自动填充                idField: 'id',                treeField: 'text',                columns: [[                                        { field: 'text', title: '名称', width: 150, halign: 'center', align: 'left', sortable: true },                    { field: 'no', title: '编码', width: 150, halign: 'center', align: 'left', sortable: true }                ]]            })        }

treeField属性指定作为节点控制的字段,我们使用text作为其字段。

4、treegrid的返回json是一个树结构,且展开子节点时是用id参数把当前节点的主键值传递过去的。在DeptList.aspx.cs文件中,修改GetDepts方法如下:

        /// <summary>        /// 根据查询条件获取部门。        /// </summary>        /// <param name="id">当前的父ID。</param>        /// <param name="keyWord">关键字</param>        /// <returns></returns>        [ExceptionBehavior(true)]        public List<Dept> GetDepts(string id, string keyword)        {            //添加一个json转换器            ServiceContext.Current.Converters.Add(new DeptJsonConverter());            var result = new List<Dept>();            using (var context = new DbContext())            {                //查询出父部门                Dept parent = null;                if (!string.IsNullOrEmpty(id))                {                    parent = context.Depts.Get(id);                    if (parent == null)                    {                        return result;                    }                }                //创建一个Dept的树实体持久化对象                var persister = context.CreateTreePersister<Dept>();                //查询出它的所有孩子                foreach (var child in persister.QueryChildren(parent).ToList())                {                    child.Children = new List<Dept>();                    //再判断一下这个孩子是否还有孩子                    child.HasChildren = persister.HasChildren(child);                    result.Add(child);                }                return result;            }        }

在每展开一个节点的时候,treegrid都会来请求该方法,id即当前节点的主键值。Fireasy提供了EntityTreePersister这样一个类,可以方便的查询出下级孩子,插入节点,移动节点等。

DeptJsonConverter类是一个json格式的转换类,我们查看其基类TreeNodeJsonConverter可得知,它实则是提供treegrid所需的json数据格式,如:

{ id: "", text: "", children: [], state: "closed", attributes: { } }

它的构造方法是传入一个字典类型,指定其他属性值,比如 text、no、attributes 等等。id不用指定,在基类里已经输出了,因为ITreeNode接口有一个Id属性的(如果实体类型的主键不是ID或不是string类型,要想办法实现它)。

        PRivate class DeptJsonConverter : TreeNodeJsonConverter<Dept>        {            public DeptJsonConverter()                : base(new Dictionary<string, Func<Dept, object>>                     {                         { "text", s => s.Name },                         { "no", s => s.No },                        { "attributes", s => new { no = s.No } }                    })            {            }        }

好了,DeptList页面的修改就完成了,如果你现在迫不急待的想看到结果如何,可以在TB_Dept表里加入三条数据(注意NO的编码规则):

浏览DeptList.aspx页面,如果人品较好的话,应该能看到树结构数据了:

二、部门编辑页面

DeptEdit.aspx看似简单,其实要处理的地方很多,0^0,我们需要让部门创建到某一个节点下,或是从某一节点移动到某一节点,这里有几个细节的地方必须得说明一下。

首先,得介绍一下Html扩展。Fireasy提供了类似MVC的HTML扩展标记,并由Fireasy.EasyUI组件提供了丰富的easyui扩展,比如TextBox、ComboBox、ComboTree、DateBox、NumberBox等等,具体可以查看Fireasy.EasyUI组件中的类。

那么,在DeptEdit.aspx(以后的所有Edit页面都会存在)中,看这一段代码:

    <% var Html = new HtmlHelper<Webapplication.Data.Model.Dept>(); %>    <div data-options="region:'center',border:false">        <table class="form-body">                        <tr>                <td class="addon">ID</td>                <td><%= Html.TextBox(s => s.Id) %></td>            </tr>            <tr>                <td class="addon">编码</td>                <td><%= Html.TextBox(s => s.No) %></td>            </tr>            <tr>                <td class="addon">名称</td>                <td><%= Html.TextBox(s => s.Name) %></td>            </tr>            <tr>                <td class="addon">排序</td>                <td><%= Html.TextBox(s => s.OrderNo) %></td>            </tr>        </table>    </div>

第一行定义了一个Html变量,它是基于实体类型的HTML扩展,在使用EasyUI扩展的时候,就可以把相应的属性引用进来了。使用基于实体类型的HTML扩展还有一个好处,实体的验证规则,如必填、长度、小数位数等,都是通过实体类型的*Metadata类来定义的,可以看*_EX.cs文件。

DeptEdit页面需要增加一个域,用来选择上级单位。随便把No删掉,把排序改成NumberBox。

    <% var Html = new HtmlHelper<WebApplication.Data.Model.Dept>(); %>    <div data-options="region:'center',border:false">        <table class="form-body">            <tr>                <td class="addon">上级部门</td>                <td><%= Html.ComboTree("cboParent").MarkNoClear() %></td>            </tr>            <tr>                <td class="addon">名称</td>                <td><%= Html.TextBox(s => s.Name) %></td>            </tr>            <tr>                <td class="addon">排序</td>                <td><%= Html.NumberBox(s => s.OrderNo) %></td>            </tr>        </table>    </div>

修改js代码,加入一个loadDepts函数,沿用DeptList.aspx.cs中的方法,只是需要增加两个参数,targetId和currentId,targetId是combobox中选中的节点,即当前部门的父部门,currentId是当前修改的部门ID。GetDepts方法的修改呆会再介绍。

        var pid = '<%= Request.QueryString["parentId"] %>';        //加载模块        function loadDepts() {            $('#cboParent').combotree({                url: "DeptList.ajx/GetDepts?targetId=" + pid + '&currentId=' + id,                panelWidth: 260,                onLoadSuccess: function () {                    $('#cboParent').combotree('setValue', pid);                }            })        }

pid在添加部门的时候是从DeptList.aspx,修改DeptList.aspx的addInfo函数如下:

        //添加信息        function addInfo() {            var row = $('#dg').treegrid('getSelected');            var parentId = row == null ? '' : row.id;            common.showDialog('DeptEdit.aspx?parentId=' + parentId, '部门', 500, 300, function () {                $('#dg').treegrid('reload');            });        }

返回到DeptEdit.aspx,修改loadInfo函数,在新增和修改场景下加入loadDepts函数:

        //加载信息        function loadInfo() {            if (id != '') {                $.getJSON('DeptEdit.ajx/GetDept?id=' + id, function (data) {                    common.processResult(data,