MVC+Jquery easyui实现无限级部门小示例

来源:互联网 发布:java实例代码 编辑:程序博客网 时间:2024/04/29 10:10

 

使用jquery easyui和MVC实现无限级部门的treeview 升降级 重命名 新增等功能。

1、效果预览:

2、Department数据库设计:

Description暂时未用和Deep只是识别了一下深度为0的为root级部门(可以换用ParentId==null识别,Deep虽只是标示了root级别部门但在实现升降时候也做了相应的处理)。

复制代码
CREATE TABLE [dbo].[Department](    Id int identity(1,1) NOT NULL,     Name nvarchar(50) NOT NULL,    [Description] nvarchar(400) NOT NULL,    ParentId int NULL,    Deep int NOT NULL default(0),)--主键ALTER TABLE [dbo].[Department]    ADD CONSTRAINT [PK_Department]    PRIMARY KEY (Id)--自引用外键ALTER TABLE [dbo].[Department]    ADD CONSTRAINT [FK_Department_ParentId]     FOREIGN KEY (ParentId)    REFERENCES [dbo].[Department] (Id)
复制代码


3、数据访问使用的是NHibernate 使用codesmith生成,并加以改造。

默认生成的hbm和model使用起来不是很方便hbm增加一个one-to-many的Departments来获取当前Department下的子部门。

改造后的hbm文件内容如下:

复制代码
<?xml version="1.0" encoding="utf-8" ?><hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="IMubiao.Data.DomainModels" assembly="IMubiao.Data">    <class name="IMubiao.Data.DomainModels.Department, IMubiao.Data" table="[dbo].[Department]" lazy="true">        <id name="Id" column="[Id]">             <generator class="native" />        </id>        <property name="Name" column="[Name]" />        <property name="Description" column="[Description]" />        <property name="Deep" column="[Deep]" />        <many-to-one name="DepartmentMember" column="[ParentId]" class="Department" />    <bag name="Departments" lazy="true" cascade="all-delete-orphan" inverse="true" >      <key column="[ParentId]"></key>      <one-to-many class="Department"></one-to-many>    </bag>        <bag name="Hrms" lazy="true" cascade="all-delete-orphan" inverse="true" >            <key column="[DepartmentId]"></key>            <one-to-many class="Hrm"></one-to-many>        </bag>    </class></hibernate-mapping>
复制代码


对模板生成的model也要进行相应的修改(对应修改的hbm文件进行相应处理)

?
privateIList<Department> _dep = newList<Department>();
       [JsonProperty]
       publicvirtual IList<Department> Departments
       {
           get { return_dep; }
           set
           {
               OnDepartmentsChanging();
               _dep = value;
              OnDepartmentsChanged();
           }
       }
       partial voidOnDepartmentsChanging();
       partial voidOnDepartmentsChanged();

涉及到的view index.aspx(显示效果就是开头的预览图效果)两个easyui-window 做部门降级和新增的容器 代码:

?
<divclass="easyui-panel"title="部门管理"icon="icon-option"collapsible="true"minimizable="true"
        maximizable="false"style="height: 500px; padding: 10px; background: #fafafa;">
        <ulid="department_tree"style="height: 350px;">
        </ul>
        <divid="department_tree_menu"class="easyui-menu"style="width: 120px;">
            <div onclick="dep_up()"iconcls="icon-up">
                升级</div>
            <div onclick="dep_down()"iconcls="icon-down">
                降级</div>
            <div class="menu-sep">
            </div>
            <div onclick="dep_rename()"iconcls="icon-rename">
               重命名</div>
            <div class="menu-sep">
            </div>
            <div onclick="department_add(0)"iconcls="icon-add">
               新增子部门</div>
        </div>
        <div id="show_d_tree"class="easyui-window"closed="true"title="选择上级部门"iconcls="icon-list"
            style="width: 200px; height: 300px; padding: 5px; background: #fafafa;">
            <div class="easyui-layout"fit="true">
               <div region="center"border="false"style="padding: 10px; background: #fff; border: 1px solid #ccc;">
                   <div id="load_tree">
                   </div>
               </div>
            </div>
        </div>
        <div id="department_add"class="easyui-window"closed="true"title="新增部门"iconcls="icon-add"
            style="width: 300px; height: 200px; padding: 5px; background: #fafafa;">
            <div class="easyui-layout"fit="true">
               <div region="center"border="false"style="padding: 10px; background: #fff; border: 1px solid #ccc;">
                   <div>
                       <ul>
                           <li style="list-style-type: none; height: 30px;">
                               <input type="hidden"id="parent_id"value=""/>
                               <label>
                                   上级部门:</label><labelid="parent_text"style="color: Green;">无</label></li>
                           <li style="list-style-type: none; height: 30px;">
                               <label for="department_name">
                                   部门名称:</label><inputtype="text"id="department_name"/>
                           </li>
                           <li style="list-style-type: none; height: 30px;"><ahref="javascript:department_create()"
                               class="easyui-linkbutton"icon="icon-save">保存</a></li>
                       </ul>
                   </div>
               </div>
            </div>
        </div>
        <div style="margin: 10px;">
            <a href="javascript:department_add()"class="easyui-linkbutton"icon="icon-add">新增部门</a>
            <a href="javascript:reload();"class="easyui-linkbutton"icon="icon-reload">重新加载</a>
        </div>
    </div>

部门降级用到了一个PreDown.aspx的PartialView 代码如下:

?
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int>" %>
<ulid="pre_down">
</ul>
<listyle="list-style-type: none; margin-top: 5px;">
    <labelfor="selected">
        已选择:</label><labelid="selected"style="color: Green;">未选择</label></li>
<listyle="list-style-type: none;">
    <inputtype="hidden"id="id_transfer"value="<%=Model %>" />
    <inputtype="hidden"id="selected_id"/>
    <ahref="javascript:submit_down()"icon="icon-ok"class="easyui-linkbutton">确认降级</a></li>
<scripttype="text/javascript">
    $(function () {
        $('#pre_down').tree({
            checkbox: false,
            url: '<%=Url.Action("PreDownData","Department",new {id=Model}) %>?' + new Date().getTime(),
            onClick: function (node) {
               $('#selected').text(node.text);
               $('#selected_id').val(node.id);
               $(this).tree('toggle', node.target);
            }
        });
    });
    function submit_down() {
        $.post('<%=Url.Action("Down","Department") %>', { id: $('#id_transfer').val(), pid: $('#selected_id').val() }, function () {
            $('#show_d_tree').window('close');
            $('#department_tree').tree('reload');
        });
    }
</script>

效果预览:

部门降级只能降至当前部门上级部门的子部门一下部门,也就是这个原因没有使用easyui tree的拖拽功能去做功能调整。

用到的几个js function:

?
<script type="text/javascript">
//初始化部门的tree
        $(function() {
           $('#department_tree').tree({
               animate: true,
               url: '<%=Url.Action("DataList","Department") %>',
               onClick: function(node) {
                   $(this).tree('toggle', node.target);
               },
               onDblClick: function(node) {
                   $('#department_tree').tree('beginEdit', node.target);
               },
               onAfterEdit: function(node) {
                   $.post('<%=Url.Action("Edit","Department") %>', { id: node.id, name: node.text });
                   reload();
               },
               onContextMenu: function(e, node) {
                   e.preventDefault();
                   $('#department_tree').tree('select', node.target);
                   $('#department_tree_menu').menu('show', {
                       left: e.pageX,
                       top: e.pageY
                   });
               }
           });
        });
//刷新部门树
        function reload() {
           $('#department_tree').tree('reload');
        }
//部门升级
        function dep_up() {
           var node = $('#department_tree').tree('getSelected');
           $.post('<%=Url.Action("UP","Department") %>', { id: node.id },function () {
               $('#department_tree').tree('reload');
           });
        }
//部门降级
        function dep_down() {
           var node = $('#department_tree').tree('getSelected');
           $('#load_tree').empty().load('<%=Url.Action("PreDown","Department") %>/'+ node.id, function() {
               $('#show_d_tree').window('open');
           });
        }
//重命名
        function dep_rename() {
           var node = $('#department_tree').tree('getSelected');
           $('#department_tree').tree('beginEdit', node.target);
        }
//新增部门
        function department_add(val) {
           if (val == undefined || val == null) {
               $('#parent_id').val('');
               $('#parent_text').text('无');
           }
           else {
               var node = $('#department_tree').tree('getSelected');
               $('#parent_id').val(node.id);
               $('#parent_text').text(node.text);
           }
           $('#department_name').val('');
           $('#department_add').window('open');
        }
//新增窗体里保存按钮的提交操作
        function department_create() {
           var pid = $('#parent_id').val();
           var name = $('#department_name').val();
           name = encodeURIComponent(name);
           $.post('<%=Url.Action("Create","Department") %>', { pid: pid, name: name });
           reload();
           $('#department_add').window('close');
        }
    </script>

DepartmentController Actions说明:

提供无限级tree数据的DataList 内容:

?
public string DataList(int? id)
       {
           var preModel = db.Departments.Where(x => x.Deep == 0);
           return Convert(preModel).ToJson();
       }
       private List<Models.EUITreeModel> Convert(IQueryable<Department> model)
       {
           List<Models.EUITreeModel> result = newList<Models.EUITreeModel>();
           foreach (varv inmodel)
          {
              var temp = new Models.EUITreeModel
              {
                  id = v.Id,
                  text = v.Name,
                  attributes = string.Empty,
                  iconCls = string.Empty,
              };
              if (v.Departments.Count > 0)
              {
                  temp.children = Convert(v.Departments.AsQueryable());
              }
              result.Add(temp);
          }
          return result;
       }

Convert方法做无限级部门的递归,绑定jquery easyui tree data。

对应 jquery easyui tree 的EUITreeModel 属性:

?
public class EUITreeModel
   {
       publicint id { get;set; }
       publicstring text { get; set; }
       publicstring iconCls { get; set; }
       publicbool @checked{ get;set; }
       publicList<EUITreeModel> children { get;set; }
       publicstring attributes {get; set; }
   }

其他一些Action辅助做一些数据的更新和新增工作!