使用Ajax.ActionLinks进行MVC 4主题切换

时间:2013-12-09 17:54:21

标签: asp.net-mvc-4 actionlink asp.net-mvc-partialview

此问题的全文可通过屏幕截图here

获取

感谢您的帮助 - 原帖如下:

所以我下载了MvcMusicStore并启动了已完成的项目。我阅读了所有关于扩展视图引擎和使用jquery插件的文章,但我想相信只需更改单击链接时的CSS文件路径就可以了。主要是因为我不想逐字复制代码,我并不完全理解。我对MVC很新。

所以这就是我所做的:

To HomeController.cs我补充道:

    public ActionResult Theme(string themeName)
    {
        ViewBag.Theme = ThemeModel.GetSetThemeCookie(themeName);
        return View();
    }

到模特我添加了这个类:

public class ThemeModel
{
    public static string GetSetThemeCookie(string theme)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("userTheme");
        string rv = "Blue";
        if (theme != null)
            rv = theme;
        else
        {
            if (cookie != null)
                rv = cookie["themeName"];
            else
                rv = "Blue";
        }

        cookie = new HttpCookie("userTheme");
        HttpContext.Current.Response.Cookies.Remove("userTheme");
        cookie.Expires = DateTime.Now.AddYears(100);
        cookie["themeName"] = rv;
        HttpContext.Current.Response.SetCookie(cookie);
        return rv;

    }
}

然后我创建了2个Site.css副本,只更改了背景颜色和font-family以及一个视图来生成我的链接标记。

<link href="@Url.Content(string.Format("~/Content/{0}.css", ViewBag.Theme))" rel="stylesheet" type="text/css" />

最后,我对_Layout.cshtml进行了这些更改。

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    @if (ViewBag.Theme == null) {Html.RenderAction("Theme", "Home");}

<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" 
    type="text/javascript"></script>
</head>
<body>
<div id="header">
    <h1><a href="/">ASP.NET MVC MUSIC STORE</a></h1>
    <ul id="navlist">
        <li class="first"><a href="@Url.Content("~")" id="current">Home</a></li>
        <li><a href="@Url.Content("~/Store/")">Store</a></li>
        <li>@{Html.RenderAction("CartSummary", "ShoppingCart");}</li>
        <li><a href="@Url.Content("~/StoreManager/")">Admin</a></li>
    </ul>
</div>

@{Html.RenderAction("GenreMenu", "Store");}

<div id="main">
    @RenderBody()
</div>

<div id="footer">
    Themes: @Ajax.ActionLink("Coral", "Theme", "Home", new { themeName = "Coral" }, null, new { @style = "color : coral"} )
        @Ajax.ActionLink("Blue", "Theme", "Home", new { themeName = "Blue" }, null, new { @style = "color : blue;"})

</div>
</body>
</html>

当我运行应用程序时,我得到了两次渲染的总体布局。一旦只有左侧呈现的流派菜单,而在身体中没有任何内容。然后是前5张专辑。我无法发布图片,因为我没有足够的代表。

当我点击我的珊瑚和蓝色链接时,我的主题发生了变化,我只得到了没有前五张专辑的一套。

所以经过这里的更多阅读后我尝试了这个:

_Layout.cshtml:

@{Html.RenderAction("Theme", "Home");}

HomeController.cs

    public ActionResult Theme(string themeName)
    {
        ViewBag.Theme = ThemeModel.GetSetThemeCookie(themeName);
        return PartialView();
    }

但即使这会停止重复渲染,当我点击主题链接时,颜色会发生变化,但我在页面上绝对没有其他内容。

现在真的很麻烦,可以真正使用一些帮助。

干杯, .PD。

1 个答案:

答案 0 :(得分:1)

好的 - 这就是我最终如何做到的。

创建一个javascript文件。我叫做master.js:

function ajaxSuccSetTheme(theme) {
    $('#linkTheme').attr('href', '/Content/' + theme + '.css');
}

修改_Layout.cshtml:

@{
    if (ViewBag.Theme == null) {
        ViewBag.Theme = MvcMusicStore.Models.ThemeModel.GetSetThemeCookie();
    }
}
<link id="linkTheme" href="@Url.Content(string.Format("~/Content/{0}.css", ViewBag.Theme))" rel="stylesheet" type="text/css" />

<script src="@Url.Content("~/Scripts/jquery-2.0.3.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/master.js")" type="text/javascript"></script>

注意事项:

  • 第一次页面加载主题不会被写入ViewBag
  • 在{/ l>上面的js文件中为<link>标记提供与jQuery选择器相同的ID
  • 将不显眼的ajax jQuery文件更新为与jQuery lib相同的版本。没有它,你的Ajax.ActionLink将无法运行。

然后我在_Layout.cshtml中的主题切换链接如下所示:

<div id="footer">
    Themes :
        @Ajax.ActionLink("Coral", "Theme", "Home", new { themeName = "Coral" }, 
            new AjaxOptions { HttpMethod = "POST", OnSuccess = string.Format("ajaxSuccSetTheme('{0}');", "Coral")}, 
            new { @style = "color : coral;" }) | 
        @Ajax.ActionLink("Blue", "Theme", "Home", new { themeName = "Blue" }, 
            new AjaxOptions { HttpMethod = "POST", OnSuccess = string.Format("ajaxSuccSetTheme('{0}');", "Blue")}, 
            new { @style = "color : blue;" })
</div>

注意事项:

  • themeName =“whatever”是Theme Controller方法的参数。这将传递给ThemeModel中的cookie方法
  • method = POST所以IE不会缓存它,我已经阅读了其他几个通过不做GET解决的问题
  • 你必须将自己的args用于OnSuccess js回调

接下来HomeController.cs改变了:

    public ActionResult Theme(string themeName)
    {
        ViewBag.Theme = ThemeModel.GetSetThemeCookie(themeName);
        if (Request.IsAjaxRequest())
        {
            return PartialView();
        }
        else
        {
            return null;
        }
    }

老实说,如果你只是在没有检查IsAjaxRequest()的情况下返回null并不重要,我们需要的就是设置cookie,以便下次登录时记住它。

只是将Cookie设置方法保留在ThemeModel中:

public class ThemeModel
{
    public static string GetSetThemeCookie(string theme = null)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("userTheme");
        string rv = "Blue";
        if (theme != null)
            rv = theme;
        else
        {
            if (cookie != null)
                rv = cookie["themeName"];
            else
            {
                cookie = new HttpCookie("userTheme");
                rv = "Blue";
            }
        }

        cookie.Expires = DateTime.Now.AddYears(100);
        cookie["themeName"] = rv;
        HttpContext.Current.Response.SetCookie(cookie);
        return rv;

    }
}
希望我帮助过某个人。如果您更愿意在jQuery中执行Tim Vanfosson's Theme Manager jQuery Plugin

干杯,

.PD。