zoukankan      html  css  js  c++  java
  • ASP.NET MVC之持久化TempData及扩展方法(十三)

    前言

    之前在开始该系列之前我们就讲述了在MVC中从控制器到视图传递数据的四种方式,但是还是存在一点问题,本节就这个问题进行讲述同时进行一些练习来看看MVC中的扩展方法。

    话题

    废话不必多说,我们直接进入主题,关于TempData的基本用法就不需要再进行讲述,其生命周期确实很短,但是对于其用法也就存在一定可能性,当我们需要从一个页面到另外一个页面进行数据传递时,此时就需要用到该对象。该对象数据进行第一次加载后则其生命周期结束,但是我们如何做到持久化该对象中的数据呢?请往下看。

    持久化TempData

    我们首先来看一个例子。

        public class TempDataController : Controller
        {
            public ActionResult Index()
            {
                TempData["cnblogs"] = "xpy0928";
                return View();
            }
    
            public ActionResult GetTemData()
            {
                var blogName = TempData["cnblogs"].ToString();
                return View();
            }
    
        }

    当第一次访问 GetTemData 时,会正确显示 blogName = "xpy0928" ,当刷新该页面时则出现【未将该对象实例化到对象的实例】。

    那么问题来了,我们如何持久化该TempData中的数据即刷新该页面时使该对象的数据不为null。 

    原来在MVC中是利用 Keep 方法来实现该对象中的数据持久化。我们来看看。

        public class TempDataController : Controller
        {
            public ActionResult Index()
            {
                TempData["cnblogs"] = "xpy0928";
                TempData.Keep();
                return View();
            }
    
            public ActionResult GetTemData()
            {
                var blogName = TempData["cnblogs"].ToString();
                TempData.Keep("cnblogs");
                return View();
            }
    
        }

    此时当我们即使多次刷新页面GetTemData视图时则该对象的键cnblogs对应的值都一直存在。 

    RedirectToRouteResult和RedirectResult

    下面我们再来看一例。

            public ActionResult Index()
            {
                TempData["cnblogs"] = "xpy0928";
                return new RedirectToRouteResult(new
                            RouteValueDictionary(new { controller = "TempData", action = "GetTemData" }));
            }
    
            public ActionResult GetTemData()
            {
                var blogName = TempData["cnblogs"].ToString();
                TempData.Keep("cnblogs");
                return View();
            }

    在上述中我们在Index方法中未直接调用 TempData.Keep() ,此时直接重定向到GetTemData方法,当再次刷新时,该对象中的值仍存在。也就是说RedirectToRouteResult默认是一直调用TempData.Keep方法使其对象的值一直存在(对于RedirectResult同理)。

    void Keep()

    在当前Action方法中调用Keep方法则保证在当前请求中TempData对象中所存储的键都不会被移除。

    void Keep(string key)

    在当前Action方法中调用Keep方法保证在当前请求中TempData对象中的某一特定项不会被移除。

    总结

    (1)当利用TempData对象存储值而未调用TempData.Keep方法时,此时只要该对象被已读,然后该对象中的所有项将被标记为删除状态。

    (2)若调用TempData.Keep(string key)方法,此时不会进行标记。

    (3)RedirectToRouteResult和RedirectResult总是会调用TempData.Keep()方法,保证该对象中的所有项不会被移除。

     MVC扩展方法

    这一小节的写出是通过对出现的问题进行解决而想到,下面我将一步一步来进行演示。

    在实际应用中我们会遇到利用Tab来切换得到不同的视图。下面我们用Bootstrap来实现,如下:

    <ul id="nav" class="nav nav-tabs">
        <li class="active"><a href="/Professional/Rota">值班表</a></li>
        <li><a href="/Professional/OverValue">超有限值</a></li>
        <li><a href="/Professional/NoOverValue">无超有限值</a></li>
        <li><a href="/Professional/DifferenceWeight">差值加权</a></li>
        <li><a href="/Professional/Difference">差值</a></li>
        <li><a href="/Professional/ClassTotal">班总和</a></li>
        <li><a href="/Professional/ClassAverage">班平均</a></li>
    </ul>

    将得到如下效果:

    那么问题来了,有七个tab,那么是不是应该在每个页面都得定义如上的一个Ul,而唯一不同的只是切换不同li,则该li的样式为active呢?

    刚开始我也是这样做的,后来越想越不对劲,每个页面都这样定义一下,而只是激活点击的li为active。此时想到的是将上述Ul定义为一个母版页,而想办法对其点击的class为active即可,于是出现了如下:

    @{
        ViewBag.Title = "_TabLayout";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    <ul id="nav" class="nav nav-tabs">
        <li><a href="/Professional/Rota">值班表</a></li>
        <li><a href="/Professional/OverValue">超有限值</a></li>
        <li><a href="/Professional/NoOverValue">无超有限值</a></li>
        <li><a href="/Professional/DifferenceWeight">差值加权</a></li>
        <li><a href="/Professional/Difference">差值</a></li>
        <li><a href="/Professional/ClassTotal">班总和</a></li>
        <li><a href="/Professional/ClassAverage">班平均</a></li>
    </ul>
    @RenderBody()
    <script type="text/javascript">
        $(function () {
            $("#nav li").eq(0).addClass("active");
        });
    </script>

    其他tab都用上述js来添加样式active。(当然可直接在模板中控制点击的li再添加样式比上述更简洁,就不再演示)。

    下面我们不用Bootstrap,自定义并用MVC扩展方法来实现切换tab(利用js不再叙述)。

    (1)母版页变成如下 

    @{
        ViewBag.Title = "_TabLayout";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    @using PowerAssessmentSystem.MvcExtend;
    
    <link href="~/Content/tab.css" rel="stylesheet" type="text/css" />
    <div class="menu-tabs">
        <ul>
            <li>@Html.ActiveLink("值班表", "Rota", "Professional")</li>
            <li>@Html.ActiveLink("超有限值", "OverValue", "Professional")</li>
            <li>@Html.ActiveLink("无超有限值", "NoOverValue", "Professional")</li>
            <li>@Html.ActiveLink("差值加权", "DifferenceWeight", "Professional")</li>
            <li>@Html.ActiveLink("差值", "Difference", "Professional")</li>
            <li>@Html.ActiveLink("班总和", "ClassTotal", "Professional")</li>
            <li>@Html.ActiveLink("班平均", "ClassAverage", "Professional")</li>
          
        </ul>
    </div>
    
    @RenderBody()

    (2)@Html.ActiveLink扩展方法实现点击Active样式

        public static class ActiveHelper
        {
            public static MvcHtmlString ActiveLink(this HtmlHelper helper, string linkText, string actionName, string controllerName)
            {
                var routevalueDic = new RouteValueDictionary();
                var acName = helper.ViewContext.RouteData.Values["action"].ToString();
                var ctlName = helper.ViewContext.RouteData.Values["controller"].ToString();
                if (acName.Equals(actionName, StringComparison.OrdinalIgnoreCase))
                {
                    if (ctlName.Equals(controllerName, StringComparison.OrdinalIgnoreCase))
                    {
                        routevalueDic.Add("class", "active");
                    }
                }
     
                return helper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), routevalueDic);
            }
        }

    (3)相关样式

    a:hover {
        text-decoration: none;
        color: #f01400;
    }
    
    .menu-tabs {
        border-bottom: 1px solid #D1D6DA;
    }
    
        .menu-tabs ul {
            height: 45px;
            line-height: 45px;
        }
    
        .menu-tabs li {
            list-style-type: none;
            float: left;
            height: 100%;
            text-align: center;
            width: 13.63636364%;
        }
    
        .menu-tabs a {
            display: block;
            font-size: 16px;
        }
    
    .active {
        color: #f01400;
        font-weight: bold;
        border-bottom: 2px solid #f01400;
        height: 55px;
    }

    我们再来看看最终的演示效果:

    总结

    本节我们讲解了TempData的持久化以及MVC中扩展方法,本节结束。

  • 相关阅读:
    Java 异常Exception e中e的getMessage()和toString()以及 e.printStackTrace();方法的区别
    js几秒以后倒计时跳转示例
    Java读取property配置文件
    js 设置下拉框的默认值
    JS的可枚举性
    Object的原型拷贝-create、assign、getPrototypeOf 方法的结合
    JS 事件循环机制
    vue nextTick深入理解-vue性能优化、DOM更新时机、事件循环机制
    vue 实战问题-watch 数组或者对象
    vue2.0读书笔记2-进阶
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/5511308.html
Copyright © 2011-2022 走看看