在需要处理很多分类以及导航的时候,树形导航菜单就比较适合。例如在汽车之家上:

页面主要分两部分,左边是导航菜单,右边显示对应的内容。现在,我们就在ASP.NET MVC 4 下临摹一个,如下:

实现的效果包括:
1、点击导航菜单上的品牌,左侧显示该品牌下的所有车型。
2、点击导航菜单上的车系,左侧显示该车系下的所有车型。
3、点击左侧上方的字母导航,锚点跳到导航菜单的对应部分。
4、页面加载完毕,显示所有品牌和车系,即树形导航完全展开。
5、点击导航菜单上的品牌,收缩或展开对应的车系,收缩时,品牌前面图标为+号,展开时,品牌前面的图片为-号。
......

源码部分,在这里

思路呢?

页面分成左右2部分,使用Bootstrap轻松实现:

<div class="row">
    <div class="col-md-2 col-lg-2 col-sm-2">
    </div>
    <div class="col-md-10 col-lg-10 col-sm-10">
    </div>
</div>

左侧最上方的字母导航,被放在一个div中,页面加载的时候向控制器动态请求。

品牌上方的字母归类,比如奥迪上方的字母A,实际上是一个div。

品牌和车系放在了ul中,比如奥迪品牌以及奥迪下的奥迪A4和奥迪A6车系。车系被放在了dl中。

树形菜单采用模版比较合适,先把数据填充到模版,再把模版追加到页面元素。

当点击左侧树形导航上的品牌或车系,右侧通过iframe来呈现对应的内容。

领域先行。有关品牌和车系就抽象成如下的类:

    public class CarCategory
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public string Name { get; set; }
        public string FirstLetter { get; set; }
        public string AnchorName { get; set; }
        public int Level { get; set; }
        public short DelFlag { get; set; }
    }

有关车型就抽象成如下的类:

    public class Car
    {
        public int Id { get; set; }
        public int PinPaiId { get; set; }
        public int CheXiId { get; set; }
        public string Name { get; set; }
    }

页面左侧呈现树形导航需要向控制器请求json数据,大致格式是:

首字母
锚点名称
所有品牌
    品牌编号
    品牌名称
    所有车系
        车系编号
        车系名称
        车系下车型的总数量

貌似有3层,那就从最里面这层开始建模。有关车系在树形导航中的显示:

    public class CheXiForDisplay
    {
        public int CheXiId { get; set; }
        public int TotalCount { get; set; }
        public string CheXiName { get; set; }
    }

有关品牌在树形导航中的显示:

    public class PinPaiForDisplay
    {
        public int PinPaiId { get; set; }
        public string PinPaiName { get; set; }
        public List<CheXiForDisplay> CheXis { get; set; }
    }

有关品牌车系分组的:

    public class PinPaiCheXiForDisplay
    {
        public string FirstLetter { get; set; }
        public string Anchor { get; set; }
        public List<PinPaiForDisplay> PinPais { get; set; }
    }

数据源从哪里来?模拟了一个:

    public class Database
    {
        public static IEnumerable<CarCategory> GetAllCarCategories()
        {
            return new List<CarCategory>
            {
                new CarCategory(){Id = 1, ParentId = 0, Name = "奥迪",FirstLetter = "A", AnchorName = "AA", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 2, ParentId = 0, Name = "宝马",FirstLetter = "B", AnchorName = "BB", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 3, ParentId = 0, Name = "保时捷",FirstLetter = "B", AnchorName = "BB", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 4, ParentId = 0, Name = "长安",FirstLetter = "C", AnchorName = "CC", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 5, ParentId = 0, Name = "大众",FirstLetter = "D", AnchorName = "DD", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 6, ParentId = 0, Name = "东风",FirstLetter = "D", AnchorName = "DD", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 7, ParentId = 0, Name = "丰田",FirstLetter = "F", AnchorName = "FF", Level = 1, DelFlag = 0},
                new CarCategory(){Id = 8, ParentId = 0, Name = "福特",FirstLetter = "F", AnchorName = "FF", Level = 1, DelFlag = 0},

                new CarCategory(){Id = 9, ParentId = 1, Name = "奥迪A4",FirstLetter = "A", AnchorName = "AA", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 10, ParentId = 1, Name = "奥迪A6",FirstLetter = "A", AnchorName = "AA", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 11, ParentId = 2, Name = "宝马1",FirstLetter = "B", AnchorName = "BB", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 12, ParentId = 2, Name = "宝马2",FirstLetter = "B", AnchorName = "BB", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 13, ParentId = 3, Name = "保时捷1",FirstLetter = "B", AnchorName = "BB", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 14, ParentId = 3, Name = "保时捷2",FirstLetter = "B", AnchorName = "BB", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 15, ParentId = 4, Name = "长安1",FirstLetter = "C", AnchorName = "CC", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 16, ParentId = 4, Name = "长安2",FirstLetter = "C", AnchorName = "CC", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 17, ParentId = 5, Name = "大众1",FirstLetter = "D", AnchorName = "DD", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 18, ParentId = 5, Name = "大众2",FirstLetter = "D", AnchorName = "DD", Level = 2, DelFlag = 1},

                new CarCategory(){Id = 19, ParentId = 6, Name = "东风1",FirstLetter = "D", AnchorName = "DD", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 20, ParentId = 6, Name = "东风2",FirstLetter = "D", AnchorName = "DD", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 21, ParentId = 7, Name = "丰田1",FirstLetter = "F", AnchorName = "FF", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 22, ParentId = 7, Name = "丰田2",FirstLetter = "F", AnchorName = "FF", Level = 2, DelFlag = 0},

                new CarCategory(){Id = 23, ParentId = 8, Name = "福特1",FirstLetter = "F", AnchorName = "AFF", Level = 2, DelFlag = 0},
                new CarCategory(){Id = 24, ParentId = 8, Name = "福特2",FirstLetter = "F", AnchorName = "AFF", Level = 2, DelFlag = 0}
            };
        }

        public static IEnumerable<Car> GetAllCars()
        {
            return new List<Car>
            {
                new Car(){Id = 1, PinPaiId = 1, CheXiId = 9, Name = "奥迪A401"},
                new Car(){Id = 2, PinPaiId = 1, CheXiId = 9, Name = "奥迪A402"},
                new Car(){Id = 3, PinPaiId = 1, CheXiId = 10, Name = "奥迪A601"},
                new Car(){Id = 4, PinPaiId = 1, CheXiId = 10, Name = "奥迪A602"},

                new Car(){Id = 5, PinPaiId = 2, CheXiId = 11, Name = "宝马101"},
                new Car(){Id = 6, PinPaiId = 2, CheXiId = 11, Name = "宝马102"},
                new Car(){Id = 7, PinPaiId = 2, CheXiId = 12, Name = "宝马201"},
                new Car(){Id = 8, PinPaiId = 2, CheXiId = 12, Name = "宝马202"},

                new Car(){Id = 9, PinPaiId = 3, CheXiId = 13, Name = "保时捷101"},
                new Car(){Id = 10, PinPaiId = 3, CheXiId = 13, Name = "保时捷102"},
                new Car(){Id = 11, PinPaiId = 3, CheXiId = 14, Name = "保时捷201"},
                new Car(){Id = 12, PinPaiId = 3, CheXiId = 14, Name = "保时捷202"},

                new Car(){Id = 13, PinPaiId = 4, CheXiId = 15, Name = "长安101"},
                new Car(){Id = 14, PinPaiId = 4, CheXiId = 15, Name = "长安102"},
                new Car(){Id = 15, PinPaiId = 4, CheXiId = 16, Name = "长安201"},
                new Car(){Id = 16, PinPaiId = 4, CheXiId = 16, Name = "长安202"},

                new Car(){Id = 17, PinPaiId = 5, CheXiId = 17, Name = "大众101"},
                new Car(){Id = 18, PinPaiId = 5, CheXiId = 17, Name = "大众102"},
                new Car(){Id = 19, PinPaiId = 5, CheXiId = 18, Name = "大众201"},
                new Car(){Id = 20, PinPaiId = 5, CheXiId = 18, Name = "大众202"},

                new Car(){Id = 21, PinPaiId = 6, CheXiId = 19, Name = "东风101"},
                new Car(){Id = 22, PinPaiId = 6, CheXiId = 19, Name = "东风102"},
                new Car(){Id = 23, PinPaiId = 6, CheXiId = 20, Name = "东风201"},
                new Car(){Id = 24, PinPaiId = 6, CheXiId = 20, Name = "东风202"},

                new Car(){Id = 25, PinPaiId = 7, CheXiId = 21, Name = "丰田101"},
                new Car(){Id = 26, PinPaiId = 7, CheXiId = 21, Name = "丰田102"},
                new Car(){Id = 27, PinPaiId = 7, CheXiId = 22, Name = "丰田201"},
                new Car(){Id = 28, PinPaiId = 7, CheXiId = 22, Name = "丰田202"},

                new Car(){Id = 29, PinPaiId = 8, CheXiId = 23, Name = "福特101"},
                new Car(){Id = 30, PinPaiId = 8, CheXiId = 23, Name = "福特102"},
                new Car(){Id = 31, PinPaiId = 8, CheXiId = 24, Name = "福特201"},
                new Car(){Id = 32, PinPaiId = 8, CheXiId = 24, Name = "福特202"}
            };
        }
    }

好,现在可以向控制器要数据了。

   public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        //获取所有首字母以及锚点的json
        public ActionResult GetFirstLettersJson()
        {
            var allCarCategories = Database.GetAllCarCategories();
            var result = from l in allCarCategories
                group l by l.FirstLetter
                into g
                select new {firstletter = g.Key, anchor=g.ToList()[0].AnchorName};
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        //获取按首字母分组后的品牌车系json
        public ActionResult GetPinPaiCheXiJson()
        {
            var allPinPais = Database.GetAllCarCategories().Where(c => c.Level == 1).OrderBy(c => c.FirstLetter);
            var allPinPaisGroup = from p in allPinPais
                group p by new
                {
                    p.FirstLetter,
                    p.AnchorName
                };

            List<PinPaiCheXiForDisplay> result1 = new List<PinPaiCheXiForDisplay>();
            foreach (var item in allPinPaisGroup)
            {
                //品牌车系
                PinPaiCheXiForDisplay pinPaiCheXiForDisplay = new PinPaiCheXiForDisplay();
                pinPaiCheXiForDisplay.FirstLetter = item.Key.FirstLetter;
                pinPaiCheXiForDisplay.Anchor = item.Key.AnchorName;

                //品牌
                List<PinPaiForDisplay> pinPaiForDisplays = new List<PinPaiForDisplay>();
                foreach (var pinpai in item.ToList())
                {
                    PinPaiForDisplay pinPaiForDisplay = new PinPaiForDisplay();
                    pinPaiForDisplay.PinPaiId = pinpai.Id;
                    pinPaiForDisplay.PinPaiName = pinpai.Name;

                    //车系
                    List<CheXiForDisplay> cheXiForDisplays = new List<CheXiForDisplay>();
                    var cheXis = Database.GetAllCarCategories().Where(c => c.ParentId == pinpai.Id).OrderBy(c => c.Id);
                    foreach (var chexi in cheXis)
                    {
                        CheXiForDisplay cheXiForDisplay = new CheXiForDisplay();
                        cheXiForDisplay.CheXiId = chexi.Id;
                        cheXiForDisplay.CheXiName = chexi.Name;
                        cheXiForDisplay.TotalCount = cheXis.Count();

                        cheXiForDisplays.Add(cheXiForDisplay);
                    }
                    pinPaiForDisplay.CheXis = cheXiForDisplays;

                    pinPaiForDisplays.Add(pinPaiForDisplay);
                }
                pinPaiCheXiForDisplay.PinPais = pinPaiForDisplays;

                result1.Add(pinPaiCheXiForDisplay);
            }

            return Json(result1, JsonRequestBehavior.AllowGet);
        }

        //根据品牌Id显示车型
        public ActionResult GetCheXingsByPId(int pid)
        {
            var cars = Database.GetAllCars().Where(c => c.PinPaiId == pid);
            return View(cars);
        }

        //根据车系Id显示车型
        public ActionResult GetCheXingsByChexiId(int cxid)
        {
            var cars = Database.GetAllCars().Where(c => c.CheXiId == cxid);
            return View(cars);
        }

    }


在Shared/_Layout.cshtml中,该引用的css,js都要引用上。

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    @Styles.Render("~/Content/css")
    @RenderSection("styles", required: false)
    @Scripts.Render("~/bundles/jquery")
    <script src="~/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    @RenderBody()


    @RenderSection("scripts", required: false)
</body>  

Home/Index.cshtml就负责显示就行了。

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section styles
{
    <link href="~/Content/sidemenu.css" rel="stylesheet" />
}

<div class="row">
    <div class="col-md-2 col-lg-2 col-sm-2">
        <!--字母导航开始-->
        <div id="lDaoHang">
        </div>
        <!--字母导航结束-->
        <!--树开始-->
        <div id="cTreeDiv" style="overflow-x: hidden; overflow-y: scroll; height: 550px; width: 99%;">
        </div>
        <!--树结束-->
        <div>
            <dl id="test"></dl>
        </div>
    </div>
    <div class="col-md-10 col-lg-10 col-sm-10">
        <div class="carContent" id="carContent">
            <iframe id="frameCar" src="" scrolling="no" frameborder="0" height="100%" width="100%" onload="this.height=this.contentWindow.document.documentElement.scrollHeight"></iframe>
        </div>
    </div>
</div>

@section scripts
{
    <script src="~/Scripts/jquery.tmpl.min.js"></script>
    <script type="text/javascript">
        $(function () {

            //加载首字母
            $.getJSON('@Url.Action("GetFirstLettersJson", "Home")', function (data) {
                $('#firstLetterTemplate').tmpl(data).appendTo('#lDaoHang');
            });

            //加载所有品牌车系
            $.getJSON('@Url.Action("GetPinPaiCheXiJson", "Home")', function (data) {
                $('#pinpaiTemplate').tmpl(data).appendTo('#cTreeDiv');

                $('.pLink').each(function () {
                    pinPaiInitialState($(this));
                });
            });

            //隐藏ifame所在div
            $("#carContent").css("display", "none");

            //点击品牌
            $('#cTreeDiv').on("click", ".pLink", function () {
                //切换
                togglePinPaiState($(this));

                //显示右边区域
                var url = "/Home/GetCheXingsByPId?pid=" + $(this).attr('id');
                $("#frameCar").attr("src", url);
                $("#carContent").css("display", "block");
            });

            //点击车系
            $('#cTreeDiv').on("click", ".cxLink", function () {
                //显示右边区域
                var url = "/Home/GetCheXingsByChexiId?cxid=" + $(this).attr('id');
                $("#frameCar").attr("src", url);
                $("#carContent").css("display", "block");
            });
        });

        //品牌的初始状态,即把车系隐藏和品牌前面的图标为+号
        var pstate = 0;

        //品牌只有2种状态:所有车系隐藏,品牌前面的图标变为为+号;要么显示品牌下的所有车系,品牌前面的图标变为-号
        //把车系隐藏和品牌前面的图标为+号,记为状态0
        //把车系隐藏和品牌前面的图标为-号,记为状态1
        function togglePinPaiState($pinpai) {


            if (pstate == 0) {
                var $i = $pinpai.parent().find("i");
                var attr = $i.attr('class');
                if (typeof attr !== typeof undefined && attr !== false) {
                    $i.removeClass("iconHide");
                }

                $i.addClass("iconShow");
                $pinpai.parent().parent().find("dl").show();
                pstate = 1;
            } else {
                var $j = $pinpai.parent().find("i");
                var attr1 = $j.attr('class');
                if (typeof attr1 !== typeof undefined && attr1 !== false) {
                    $j.removeClass("iconShow");
                }
                $j.addClass("iconHide");
                $pinpai.parent().parent().find("dl").hide();
                pstate = 0;
            }
        }

        function pinPaiInitialState($pinpai) {
            pstate = 0;
            togglePinPaiState($pinpai);
        }

    </script>

    <!--首字母模版-->
    <script id="firstLetterTemplate" type="text/x-jQuery-tmpl">
        <div class="lWrapper">
            <a href="#${anchor}" class="lLink">${firstletter}</a>
        </div>
    </script>

    <!--品牌模版-->
    <script id="pinpaiTemplate" type="text/x-jQuery-tmpl">
        <div class="lHeader" id="${Anchor}">${FirstLetter}</div>
        <ul class="uTree">
            {{if PinPais}}
            {{each PinPais}}
            <li>
                <h5 class="font-bold">
                    <a href="javascript:void(0)" class="pLink" id="${$value.PinPaiId}"><i></i>${$value.PinPaiName}</a>
                </h5>
                <dl>
                    {{tmpl(CheXis) "#chexiTemplate"}}
                </dl>
            </li>
            {{/each}}
            {{else}}
            <li>没有对应品牌</li>
            {{/if}}

        </ul>
    </script>

    <!--车系模版-->
    <script id="chexiTemplate" type="text/x-jQuery-tmpl">
        <dd><a id="${CheXiId}" href="javascript:void(0)" class="cxLink">${CheXiName}<em>(${TotalCount})</em></a></dd>
    </script>
}

以上,
○ 从控制器返回的有关树形菜单的json数据,先填充到jquery.tmpl.min.js模版中,然后追加到页面上。
○ 树形菜单的展开或收缩,通过全局变量pstate在0和1之间的切换来实现,页面初次加载给变量pstate一个初始值。

另外,点击树形导航上的品牌,iframe加载的视图是Home/GetCheXingsByPId.cshtml

@model IEnumerable<MvcApplication1.Models.Car>

@{
    ViewBag.Title = "GetCheXingsByPId";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>GetCheXingsByPId</h2>

<div>
    @foreach (var item in Model)
    {
        <p>@item.Name </p>

    }
</div>

点击树形导航上的车系,iframe加载的视图是Home/GetCheXingsByChexiId.cshtml

@model IEnumerable<MvcApplication1.Models.Car>

@{
    ViewBag.Title = "GetCheXingsByChexiId";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>GetCheXingsByChexiId</h2>

<div>
    @foreach (var item in Model)
    {
        <p>@item.Name </p>

    }
</div

就这样。

在ASP.NET MVC下实现树形导航菜单的更多相关文章

  1. ASP.NET MVC下的四种验证编程方式[续篇]

    在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注Validation ...

  2. ASP.NET MVC下的四种验证编程方式

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定 ...

  3. Response.End()在Webform和ASP.NET MVC下的表现差异

    前几天在博问中看到一个问题--Response.End()后,是否停止执行?MVC与WebForm不一致.看到LZ的描述后,虽然奇怪于为何用Response.End()而不用return方式去控制流程 ...

  4. ASP.NET MVC下的四种验证编程方式[续篇]【转】

    在<ASP.NET MVC下的四种验证编程方式> 一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式(“手工验证”.“标注ValidationAttribute特性”.“ ...

  5. ASP.NET MVC下的四种验证编程方式【转】

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...

  6. ASP.NET MVC下使用AngularJs语言(六):获取下拉列表的value和Text

    前面Insus.NET有在Angularjs实现DropDownList的下拉列表的功能.但是没有实现怎样获取下拉列表的value和text功能. 下面分别使用ng-click和ng-change来实 ...

  7. ASP.NET MVC下使用AngularJs语言(五):ng-selected

    这次学习ng-selected语法,这个是为DropDownList下拉列表显示默认选项. 演示从下面步骤开始 1,新建一个model: 上面#14行代码的property,数据类型为bool.即是存 ...

  8. ASP.NET MVC下使用AngularJs语言(二):ng-click事件

    程序用户交互,用户使用mouse点击,这是一个普通的功能. 在angularjs的铵钮点击命令是ng-click. 创建Angularjs的app使用前一篇<ASP.NET MVC下使用Angu ...

  9. ASP.NET MVC下使用AngularJs语言(一):Hello your name

    新春节后,分享第一个教程. 是教一位新朋友全新学习ASP.NET MVC下使用AngularJs语言. 一,新建一个空的Web项目.使用NuGet下载AngularJs和jQuery.二,配置Bund ...

随机推荐

  1. Shell-遍历删除指定目录

    Code: find $LibPath/ -name .svn | xargs rm -rf

  2. 浅谈tomcat中间件的优化【转】

    今天来总结一下tomcat的一些优化的方案,由于本人才疏学浅,写的不好,勿喷! tomcat对于大多数从事开发工作的童鞋应该不会很陌生,通常做为默认的开发环境来为大家服务,不过tomcat默认的一些配 ...

  3. 编程入门python之定义函数【转】

    编程入门python之定义函数 零基础学编程by学哥 2017-02-06 10:51 今天讲python函数. 输入参数求三角形或圆形或长方形的面积 先输入1个参数:形状类型 1=三角形 2=圆形 ...

  4. Casperjs循环执行(重复执行不退出)

    var casper = require('casper').create({ // pageSettings: { // loadImages: true, // loadPlugins: fals ...

  5. MongoDB 3.x 安装及权限验证

    1.首先在网上下载MongoDB的安装包,我这边使用的是3.2版本: 2.安装MongoDB安装程序,安装完成后设置环境变量,我这边的安装路径是:“C:\Program Files\MongoDB\S ...

  6. 解决spring boot JavaMailSender部分收件人错误导致发送失败的问题

    使用spring boot通常使用spring-boot-starter-mail进行邮件的发送.当进行邮件群发的话,如果一个收件人的地址错误,会导致所有邮件都发送失败.因此我们需要在邮件发送失败的时 ...

  7. 如何使用windows的计划任务?计划任务?

    我们经常有一些程序想要过了几小时来运行:比如定时关机 或者说希望能够每天的几点执行一个什么程序: 这些所有的操作都需要用到windows的任务计划:或者叫计划任务:反正都一样 下面小编将指导大家创建一 ...

  8. 在IIS下部署SSL证书实现HTTPS

    在IIS下部署SSL证书实现HTTPS   HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版.谷歌已经制定了一项长远的计划,它的最终目标是将所有通过HTTP协议呈现的网页标为“不安全” ...

  9. 【Git使用详解】Egit的常用操作详解

    常用操作 操作 说明 Fetch 从远程获取最新版本到本地,不会自动merge Merge 可以把一个分支标签或某个commit的修改合并现在的分支上 Pull 从远程获取最新版本并merge到本地相 ...

  10. IntelIJ IDEA配置Tomcat遇到问题Error during artifact deployment. See server log for details

    IntelIJ IDEA在配置tomcat的时候会遇到Error during artifact deployment. See server log for details.这样的问题,我的系统是W ...