0

我在每一页上都有一个 A - Z 目录“小部件”。如果用户在主页上并且他们单击目录中的某些内容,我想加载目录页面并加载相应的结果。但是,如果用户在目录页面上并且他们点击了某些东西,我想异步加载结果而不进行页面刷新。

目录小部件具有指向 GroupController 上的 DirectoryResult 操作方法的链接,如果它们位于目录页面上,通常会返回 PartialView。但是如果它们不在目录页面上,我会重定向到主目录操作方法,该方法返回一个视图并加载整个页面。

这是有问题的代码:

    public ActionResult DirectoryResult(string search)
    {
        if (Request.IsAjaxRequest())
        {
            var groups = _groupService.GetGroupsBySearchExpression(search);
            var premiumGroups = _groupService.FilterPremiumGroups(groups);

            return PartialView(new FundDirectoryViewModel
            {
                Groups = groups,
                PremiumGroups = premiumGroups
            });
        }
        else
        {
            TempData[UIMessageDataKeys.FundDirectorySearch] = search;
            return RedirectToAction("Directory", "Group");
        }
    }

我把这个给办公室里的一个人看,他的第一反应是“那是个黑客!”。我不知道是否同意他的观点,因为我不知道有什么更好的方法来做到这一点。

作为参考,这是每个页面上存在的小部件的定义:

<div id="DirectoryList" class="directory-list">
    <span>Fund Directory</span>

    <% var letters = new [] { "A", "B", "C", "D", "E", "F", "G", "H", "I", ... }; %>
    <% var current = (Model.Search.IsNotNullOrEmpty()) ? Model.Search : "A"; %>
    <% foreach (var letter in letters) { %>

        <span>
            // use HtmlHelper extension to generate links as our system needs them
            <%= Html.RouteActionLink("funddirectory", "DirectoryResult"
                , letter
                , (letter.ToLower() == current) ? new { @class = "active" } : new { @class = "" })%>

        </span>

    <%} %>
</div>

有没有更好的方法让我根据请求来自的页面来确定我应该返回 PartialView 还是 View ?

4

2 回答 2

2

虽然您的视图绝对可以改进以避免所有这些意大利面条代码(使用编辑器/显示模板和 HTML 帮助程序并避免在视图中硬编码字母表:-)),但操作方法对我来说似乎很好。Request.IsAjaxRequest用于确定是否已通过 AJAX 请求操作并返回部分视图,或者如果没有重定向,则非常好。

可以认为是 hack 是使用TempData而不是使用查询字符串,因为如果用户按下F5重定向的页面,他将失去上下文,但如果这是您期望的行为,那么没关系。

虽然我不熟悉上下文,但我会对你办公室的人用来支持他们认为这是黑客行为的反应的论点感兴趣。

于 2010-09-04T12:28:11.340 回答
1

虽然 Darin 是 100% 正确的,而且您的代码不是 hack,但我通常更喜欢制作两个具有不同名称和签名的 Action。如果您使用 AjaxOnly 操作过滤器,这尤其容易,例如: http ://helios.ca/2009/05/27/aspnet-mvc-action-filter-ajax-only-attribute/

public ActionResult DirectoryResult(string search)
{        
        var groups = _groupService.GetGroupsBySearchExpression(search);
        var premiumGroups = _groupService.FilterPremiumGroups(groups);

        return PartialView(new FundDirectoryViewModel
        {
            Groups = groups,
            PremiumGroups = premiumGroups
        });        
}

//optional [AjaxOnly]
public ActionResult DirectoryAjaxResult( string search )
{
        TempData[UIMessageDataKeys.FundDirectorySearch] = search;
        return RedirectToAction("Directory", "Group");
}
于 2010-09-04T13:16:37.317 回答