Dynamically Binding Menus to TreeView

本文介绍了一个基于.NET平台的导航菜单系统的构建过程,包括数据库表设计、实体类定义、数据访问层实现、业务逻辑层调用及前端展示。该系统通过存储过程从数据库中读取菜单数据,动态生成树形结构的导航菜单。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

First:

Create a table:

 --用户表
--目录参考:
--父结点1
 +--孩子结点1
 +---孩子结点2
 +--孩子结点3
--父结点2
 +--孩子结点1
 +--孩子结点2

if object_id('tb_menu','U')>0
drop table tb_menu

create table tb_menu       --目录表
(
 id   int identity(1,1)primary key, --@编号
 menuowner int not null,     --*目录所有者【系统管理员|教务人员|教师/辅导员|学生】
 menudeep int not null,     --*目录层次
 menuname varchar(50) not null,   --*目录名
 menuparent varchar(50) ,     --*目录父结点,父结点为空时表明此目录为根目录
 urlname  varchar(50)      --目录对应的链接名
)
go

 

 

then in Model layer,write codes as follows:

//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由工具生成。
//     运行库版本:2.0.50727.1433
//
//     对此文件的更改可能会导致不正确的行为,并且如果
//     重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using ISS.WDC.Framework.Data;
using ISS.WDC.Framework.Data.OM;
using ISS.WDC.Framework.Data.OM.OMAttribute;
using ISS.WDC.Framework.Data.OM.Collections;
using ISS.WDC.Framework.Data.OM.Transaction;
using ISS.WDC.Project.BaseItem;


namespace EAMS.Model
{


    /// <summary>
    /// tb_menu 实体
    /// </summary>
    [Serializable()]
    [DataTable("tb_menu")]
    public class tb_menu : Entity
    {

        private int _id;

        /// <summary>
        /// 字段名称 id
        /// </summary>
        public static string M_id = "id";

        private int _menuowner;

        /// <summary>
        /// 字段名称 menuowner
        /// </summary>
        public static string M_menuowner = "menuowner";

        private int _menudeep;

        /// <summary>
        /// 字段名称 menudeep
        /// </summary>
        public static string M_menudeep = "menudeep";

        private string _menuname;

        /// <summary>
        /// 字段名称 menuname
        /// </summary>
        public static string M_menuname = "menuname";

        private string _menuparent;

        /// <summary>
        /// 字段名称 menuparent
        /// </summary>
        public static string M_menuparent = "menuparent";
        /// <summary>
        /// 字段名称 urlname
        /// </summary>
        public static string M_urlname = "urlname";
        private string _urlname;
        /// <summary>
        /// id
        /// </summary>
        [DataField("id", "System.Int32", false, true, true, "Int32", "SEQ_tb_menu_PK")]
        public int id
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }

        /// <summary>
        /// menuowner
        /// </summary>
        [DataField("menuowner", "System.Int32", false, false, false, "Int32")]
        public int menuowner
        {
            get
            {
                return this._menuowner;
            }
            set
            {
                this._menuowner = value;
            }
        }

        /// <summary>
        /// menudeep
        /// </summary>
        [DataField("menudeep", "System.Int32", false, false, false, "Int32")]
        public int menudeep
        {
            get
            {
                return this._menudeep;
            }
            set
            {
                this._menudeep = value;
            }
        }

        /// <summary>
        /// menuname
        /// </summary>
        [DataField("menuname", "System.String", false, false, false, "String")]
        public string menuname
        {
            get
            {
                return this._menuname;
            }
            set
            {
                this._menuname = value;
            }
        }

        /// <summary>
        /// menuparent
        /// </summary>
        [DataField("menuparent", "System.String", false, false, false, "String")]
        public string menuparent
        {
            get
            {
                return this._menuparent;
            }
            set
            {
                this._menuparent = value;
            }
        }
        /// <summary>
        /// urlname
        /// </summary>
        [DataField("urlname", "System.String", false, false, false, "String")]
        public string urlname
        {
            get
            {
                return this._urlname;
            }
            set
            {
                this._urlname = value;
            }
        }
    }
}

then in IDAL layer,write codes:

using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using EAMS.Model;
using System.Collections;

namespace EAMS.IDAL
{
    public interface INav
    {
        /// <summary>
        /// 显示菜单
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        List<Model.tb_menu> selectNavmenu(int loadtype);
    }
}

and,in DataProFile layer,we override this interface:

using System;
using System.Collections.Generic;
using System.Text;
using EAMS;
using EAMS.IDAL;
using EAMS.Model;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;

namespace EAMS.DataProFile
{
    public class Nav : INav
    {

        public Nav()
        { }
        Database db = DatabaseFactory.CreateDatabase("Connection String");
        DataSet dst;
        public List<Model.tb_menu> GetNavmenu(DataTable dt)
        {
            List<Model.tb_menu> menu = new List<tb_menu>();
            foreach (DataRow row in dt.Rows)
            {
                Model.tb_menu me = new tb_menu();
                me.id= Convert.ToInt32(row["id"]);
                me.menudeep = Convert.ToInt32(row["menudeep"]);
                me.menuname = Convert.ToString(row["menuname"]);
                me.menuowner = Convert.ToInt32(row["menuowner"]);
                me.menuparent = Convert.ToString(row["menuparent"]);
                me.urlname=Convert.ToString(row["urlname"]);
                menu.Add(me);
            }
            return menu;
        }

        #region INav 成员

        List<Model.tb_menu> INav.selectNavmenu(int loadtype)
        {
            try
            {
                DbCommand dbc = db.GetStoredProcCommand("sp_selectmenu");
                db.AddInParameter(dbc, "@varloadtype ", System.Data.DbType.Int32, loadtype);
                dst = db.ExecuteDataSet(dbc);
                return GetNavmenu(dst.Tables[0]);
            }
            catch (Exception ex)
            {
                string s = ex.Message.ToString();
                throw ex;
            }
        }
        #endregion
    }
}

 

meanwhile,we should code stored procedures:

--显示导航菜单
if exists(select name from Sysobjects where name='sp_selectmenu' and type='P')
drop proc sp_selectmenu
go
create proc sp_selectmenu
@varloadtype int
as
 select id,menuowner,menudeep,menuname,menuparent,urlname
 from tb_menu
 where menuowner=@varloadtype
go

then in BLL layer,we provide this method to public:

using System;
using System.Collections.Generic;
using System.Text;
using EAMS.IDAL;
using System.Web;
using EAMS.Model;
namespace EAMS.BLL
{
    [Serializable]
    public class NavBL
    {
        /// <summary>
        ///
        /// </summary>
        private static readonly INav inav = new EAMS.DataProFile.Nav();

        public List<Model.tb_menu> nav(int loadtype)
        {
            return inav.selectNavmenu(loadtype);
        }
    }
}

 

The last, is that we call functions in BLL layer:

public void LoadMenu(int loadtype)
    {
       
        //根据登录类别,获取目录
        EAMS.BLL.NavBL nb = new NavBL();
        List<EAMS.Model.tb_menu> lstMenu = nb.nav(loadtype);
        //根目录的集合
        List<EAMS.Model.tb_menu> rootmenu = new List<EAMS.Model.tb_menu>();

        string[] sourcepath ={ "SysAdmInterfaceUnique", "ManInterfaceUnique", "TeaInterfaceUnique", "StuInterfaceUnique" };
        foreach (EAMS.Model.tb_menu menu in lstMenu)
        {
            if (menu.menudeep != 1) continue;
            rootmenu.Add(menu);
            TreeNode tn=new TreeNode();
            tn.Text=menu.menuname;
            TrvMenu.Nodes.Add(tn);
            //子目录
            foreach (EAMS.Model.tb_menu submenu in lstMenu)
            {
                if (0==submenu.menuparent.CompareTo(menu.menuname) && submenu.menudeep == 2)
                {
                    TreeNode TnSubMenu = new TreeNode();
                    TnSubMenu.Text = submenu.menuname;
                    //设置链接URL
                    if (submenu.urlname.CompareTo("") != 0)
                    {
                        TnSubMenu.NavigateUrl = "~/" + sourcepath[loadtype] + "/" + submenu.urlname + ".aspx";
                    }
                    tn.ChildNodes.Add(TnSubMenu);
                }
            }
           
        }
        TrvMenu.DataBind();
    }

 

So,All Done!

### 解决 JavaScript 中动态导入模块时遇到的 'Failed to fetch' 错误 #### 了解错误原因 在 Vue3 或其他基于 JavaScript 的项目中,`Failed to fetch dynamically imported module` 表明尝试通过网络请求获取一个模块失败了[^1]。这可能是由于路径配置不正确、服务器端资源不可达或是打包过程中某些文件未能被打包。 #### 动态路由页面引入问题分析 对于使用 Webpack 构建的应用程序来说,如果采用懒加载的方式去按需加载组件,则需要注意这些动态路由页面并没有像静态引入那样写入 `router.ts` 文件,在打包阶段可能会被忽略掉,从而造成实际部署环境中找不到对应的 `.js` 资源文件而引发此问题[^3]。 #### 实施解决方案 ##### 正确设置服务端支持 确保服务器能够正确处理对 chunk 文件(即由构建工具生成的小型化脚本片段)的 HTTP 请求,并返回适当的内容类型头信息给客户端浏览器解析执行。 ##### 修改 Webpack 配置优化打包策略 可以考虑调整 Webpack 输出目录结构以及公共路径(publicPath),使得生产环境下也能顺利找到所需的 JS/CSS 等静态资源;另外还可以启用 long-term caching 来提高缓存命中率减少不必要的重新下载次数。 ##### 使用魔法注释控制分包逻辑 为了更好地管理拆分后的代码块,可以在 import() 函数内部加入特殊的注解来指导编译器如何分割业务逻辑并指定其存放位置: ```javascript const MyComponent = () => import(/* webpackChunkName: "my-component" */ './MyComponent.vue'); ``` 这样做的好处是可以让开发者更直观地掌握各个部分之间的依赖关系同时也便于后续维护工作开展。 ##### 处理潜在的安全性和跨域问题 有时也会因为 CORS 政策限制或者是 HTTPS/HTTP 协议混用引起此类异常情况的发生。因此建议开发人员仔细检查 API 接口地址是否合法有效并且遵循同源原则设定好 Access-Control-Allow-Origin 响应头部字段值。 #### 追踪深层次的原因 利用 ECMAScript 提供的新特性——Error.cause 属性可以帮助定位到最根本的问题所在之处。当捕获到一层又一层嵌套起来的异常对象之后便可以通过查看 cause 字段得知最初触发该系列连锁反应的具体缘由是什么样的操作失误所造成的[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值