【问题标题】:How to change WebGrid action for getting data (.NET MVC3)如何更改 WebGrid 操作以获取数据(.NET MVC3)
【发布时间】:2011-08-23 12:21:10
【问题描述】:

我有一个呈现 WebGrid 的局部视图。我的控制器看起来像

public ActionResult Index()
{
    return View();
}
public ActionResult GetUserList(int? page, string sort, string sortdir)
{
    var model = UserModel.getList(page,sort,sortdir);
    return PartialView("_UserList",model);
}

Index.cshtml :
....
@Html.Action("GetUserList")

问题是每次我单击网格导航或排序链接时,它都会调用Index 方法。如何让 Webgrid 执行不同的操作(在这种情况下为GetUserList)?我确定我可以使用 jquery 将 GetUserList 添加到网格中的所有链接,但我相信这应该是一种更好的方法。
也有可能是我做错了,谢谢你的建议。

【问题讨论】:

    标签: asp.net-mvc-3 webgrid


    【解决方案1】:

    经过大量的摸索和挖掘(甚至用 WebGrid 的源代码摆弄 Reflector),我得出的结论是,使用 WebGrid,您无法控制/更改 Header 链接操作。

    要创建标头链接 URL,路径取自 HttpContext.Request.Path,因此无法自定义它以指向不同的路由。

    一个非常丑陋的黑客是利用 jQuery Ajax 的事件(因为标题链接使用 jQuery.load 进行排序)并覆盖 URL:

    <a href="#" onclick="$('#myGrid').load('/?sort=AlbumId&amp;sortdir=ASC&amp;__=634486582282704242 #myGrid');">Album Id</a>
    

    更好的解决方案是使用:

    • Telerik Grid 可让您指定 custom routes 并在呈现布局时提供更大的灵活性
    • MvcContrib Grid(不确定这是否可以让您修改标题链接,但肯定比 WebGrid 更灵活)

    【讨论】:

    • @JP:你是对的。我进行了一些挖掘,并根据发现更新了我的答案。
    • 感谢您节省了我研究此问​​题的时间。现在我必须决定如何绕过它。它所访问的 URL 会导致往返的内容过多。所以,我需要找到更好的方法。
    【解决方案2】:

    @MrChief 有上面关于丑陋黑客的想法......我把它放在一起。这是我用来执行此操作的主要代码。事实上,它确实会在 ajax 调用上线之前劫持它。关键是修改正在发送的 URL,因为网格将从 HttpContext.Request.Path 中获取该 URL。并将其插入到锚元素的 onclick 中。

    我把它放在我的主要 common.js 中,并且将简单地附加一个函数来捕获在发送数据之前发生的 ajaxSend 事件。

    // Used to hijack the sending of all AJAX calls.  Before it sends the call to the server, it checks to see if the 
    // active element (the element that prompted the call) is marked with a given class.  If so, then it will perform
    // the given operation.  
    $(document).ajaxSend(function (event, jqXHR, ajaxOptions) {
    
        var activeElement = document.activeElement;
    
        if ($(activeElement).attr('redosorturl') != null) {
    
            // If this is a sort anchor link from a grid that needs to have the sort link redone, do it here.
            // the code is in the eipGrip.js file.
            if ($(activeElement).attr('redosorturl').toString() == 'redoSortURL') {
                var newURL = RedoGridSortURL(activeElement, ajaxOptions.url.toString());
                ajaxOptions.url = newURL.toString();
            }
        }
    
        return false;
    });
    

    在渲染页面时,我在列标题中标记了包含错误 URL 的标签,其中包含一个名为“redosorturl”的类,所以我知道当我劫持 ajax 调用时,必须对这个元素进行操作。我然后调用一个给我正确 URL 的自定义函数,然后用新的 URL 重写 ajaxOptions.url。

    我必须将 activeElement 传递给该重写函数,以便我可以遍历 DOM 以获取网格信息,其中我已经放置了控制器和操作方法等数据,以及我使用的 ID 和其他信息为网址。同样,我传入当前的 url 字符串,因为网格会在我解析的 url 的末尾注入一个标记并放在新的 url 上。

    【讨论】:

      【解决方案3】:

      你的结论不正确。你只需要将你的 webgrid 包装在一个 Get 表单中:

      using (Html.BeginForm("GetUserList", "ThingaMaBob", System.Web.Mvc.FormMethod.Get))
      {
       var grid = new WebGrid(
      ...
      ));
      
          Html.Hidden(grid.SortFieldName, grid.SortColumn);
          Html.Hidden(grid.SortDirectionFieldName, grid.SortDirection == SortDirection.Ascending ? "ASC" : "DESC");
      }
      

      隐藏使得排序目录和排序字段在查询字符串中以可解析的形式结束。你最终会得到像 localhost/ThingaMaBob/GetUserList?someotherfields=whatever=&sort=city&sortdir=ASC 之类的网址

      【讨论】:

      • 不知道该说什么......这就是我们在生产网格中的方式。
      【解决方案4】:

      如果你删除 [HttpPost] 属性并让路由来相同的功能。你会在你的方法中找到 Request["page"] 值。这将允许您检查 Request["Page"] 值。

      【讨论】:

        猜你喜欢
        • 2011-12-07
        • 1970-01-01
        • 1970-01-01
        • 2011-12-15
        • 2015-07-19
        • 2012-04-23
        • 2011-12-19
        • 1970-01-01
        • 2012-11-01
        相关资源
        最近更新 更多