你在正确的轨道上。您将需要同时使用 ajax 来获取 html 以在不刷新页面的情况下呈现,以及使用推送状态来更新 URL 以包含当前选项卡。
您可以将这些事情作为单独的操作进行,但我建议使用PJAX。使用 PJAX,您将需要在服务器中添加一些额外的逻辑来决定是返回带有布局的完整 html 页面,还是只返回部分(PJAX 请求)。
这是我们的 Foo 控制器。索引有一个默认选择的“栏”选项卡。Bar 和 Baz 操作返回 Index 视图,但不同的选项卡是选定的选项卡。如果是 PJAX 请求,那么我们需要的只是填充选项卡内容的局部视图。
public class FooController : Controller
{
public ActionResult Index()
{
ViewBag.SelectedTab = "Bar";
return View();
}
public ActionResult Bar()
{
if(Request.Headers["X-PJAX"] != null)
return PartialView();
ViewBag.SelectedTab = "Bar";
return View("Index");
}
public ActionResult Baz()
{
if (Request.Headers["X-PJAX"] != null)
return PartialView();
ViewBag.SelectedTab = "Baz";
return View("Index");
}
}
在 Foo/Index.cshtml 内部,我们有 Razor 代码,它将确定要基于ViewBag.SelectedTab
.
@{
ViewBag.Title = "Foo";
}
<h2>Foo</h2>
<ul>
<li><a class="tabs" href="@Url.Action("Bar", "Foo")">Bar</a></li>
<li><a class="tabs" href="@Url.Action("Baz", "Foo")">Baz</a></li>
</ul>
<div id="tab_content">
@if(ViewBag.SelectedTab == "Bar")
{
@Html.Partial("Bar")
}
@if (ViewBag.SelectedTab == "Baz")
{
@Html.Partial("Baz")
}
</div>
@section scripts
{
<script type="text/javascript">
$(function() {
$(".tabs").pjax("#tab_content");
})
</script>
}
最后的脚本部分是您如何连接 PJAX。您是在告诉它,对于具有tabs
该类的所有超链接,使用 pjax 动态加载和呈现从 生成的 htmlhref
到具有 id 的容器中,tab_content
并将浏览器中的 url 更新为来自href
.
在这种情况下,每个选项卡的局部视图都相当简单
条形图.cshtml
<p>This is the Bar tab. No pun intended.</p>
Baz.cshtml
<p>This is the baz tab.</p>
这显然是一个非常简化的解决方案。您通常希望使用表示模型来处理视图的逻辑。此外,我有意省略了任何选项卡样式,以证明此技术可用于任何类型的链接。它不仅限于选项卡。
此示例的完整源代码可以在我的 GitHub 站点上。