本文目錄
通過實例學習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 + '¤tId=' + 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,
新聞熱點
疑難解答