向Telerik ASP.NET MVC网格传递参数

19
我有一个Telerik Asp.net MVC网格,需要根据用户在单独的文本框中输入的搜索条件进行填充。该网格使用ajax方法进行初始加载以及分页。
如何将搜索参数传递给网格,以便每次它调用ajax方法响应用户单击另一页以转到该页面上的数据时都发送这些参数?
我阅读了Telerik的用户指南,但没有提到这种情况。我能够做到以上唯一的方法是使用jquery在客户端向rebind()方法传递参数。问题是我不确定它是否是传递参数的“官方”方式,即使在更新后也始终有效。
我在Telerik网站上找到了这个方法:链接文本 我必须传入多个参数。当Telerik网格调用控制器中的操作方法并基于搜索参数再次运行查询时。
以下是我的代码片段:
$("#searchButton").click(function() {
    var grid = $("#Invoices").data('tGrid');

    var startSearchDate = $("#StartDatePicker-input").val();
    var endSearchDate = $("#EndDatePicker-input").val();

    grid.rebind({ startSearchDate: startSearchDate ,
                    endSearchDate: endSearchDate
                });
});
6个回答

10

根据Telerik的说法,"推荐的方法是在onDataBinding事件中设置参数"。

function onGridBinding(e) {
if (cancelGridBinding) {  
    // ...
}
else {
    var searchValue = 'something';
    e.data = { search: searchValue };
}

}


7

对于我自己,我使用ViewModel对象,使用jQuery和javascript对象传递,我的View是强类型的SearchMemberModel,其中包含我的搜索字段,我的视图中有一个文本框来表示每个字段。我的数据绑定是通过将Model传递给控制器实现的。然后我在javascript中构建我的对象并在rebind调用中将其传递给控制器。

这是我的代码:

View 和 javascript:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage<Enquete.Models.SearchMemberModel>" %>

<% using (Html.BeginForm()) {%>
    <%: Html.ValidationSummary(true) %>

    <fieldset>
        <legend><%: Resources.Search %></legend>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.MemberNumber) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.MemberNumber) %>
            <%: Html.ValidationMessageFor(model => model.MemberNumber) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Email) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Email) %>
            <%: Html.ValidationMessageFor(model => model.Email) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.FirstName) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.FirstName) %>
            <%: Html.ValidationMessageFor(model => model.FirstName) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.LastName) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.LastName) %>
            <%: Html.ValidationMessageFor(model => model.LastName) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Phone) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Phone) %>
            <%: Html.ValidationMessageFor(model => model.Phone) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Active) %>
        </div>
        <div class="editor-field">
            <%: Html.CheckBoxFor(model => model.Active) %>
            <%: Html.ValidationMessageFor(model => model.Active) %>
        </div>

        <p>
            <input type="submit" value="<%: Resources.ToSearch %>" id="btnSearch" />
        </p>
    </fieldset>

<% } %>

 <%= Html.Telerik().Grid<SerializableMember>()
                .Name("Grid")
                .Columns(colums =>
                 {
                     colums.Bound(c => c.Email).Title(Resources.Email);//.ClientTemplate("<a href=\"" + Url.Action(MVC.Admin.Edit()) + "/<#=Id#>\" ><#=Email#></a>");
                     colums.Bound(c => c.FirstName).Title(Resources.FirstName);
                     colums.Bound(c => c.LastName).Title(Resources.LastName);
                     colums.Bound(c => c.MemberNumber).Title(Resources.MemberNumber);
                     colums.Bound(c => c.Active).Title(Resources.Active).HeaderHtmlAttributes(new { @class = "center-text" }).HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<img src=\"Content/images/icons/<#=Active#>.png\" alt=\"<#=Active#>\" />");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.ResetPassword()) + "/<#=Id#>\" title=\"" + Resources.ResetPassword + "\" >" + Resources.ResetPassword + "</a>");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Activate()) + "/<#=Id#>\" title=\"" + Resources.Activate + "\" >" + Resources.Activate + "</a>");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Deactivate()) + "/<#=Id#>\" title=\"" + Resources.Deactivate + "\" >" + Resources.Deactivate + "</a>");
                 })
                //.DataBinding(d => d.Ajax().Select("ListAjax", "Member", Model))
                .DataBinding(d => d.Ajax().Select(MVC.Member.ListAjax(Model).GetRouteValueDictionary()))
                .Sortable()
                .NoRecordsTemplate(Resources.NoData)
        %>
        <%= Html.AntiForgeryToken() %>

        <script type="text/javascript">
            $(document).ready(function () {
                $('#btnSearch').click(function () {
                    var grid = $('#Grid').data('tGrid');
                    var searchModel = {
                        MemberNumber: $('#MemberNumber').val(),
                        Email: $('#Email').val(),
                        FirstName: $('#FirstName').val(),
                        LastName: $('#LastName').val(),
                        Phone: $('#Phone').val(),
                        Active: $('#Active').is(':checked')
                    };
                    grid.rebind(searchModel);
                    return false;
                });
            });
        </script>

        <%= Html.Telerik().ScriptRegistrar().jQuery(false).DefaultGroup(g => g.DefaultPath("~/Content/Javascript/2010.3.1110"))%>

这是我的控制器。
[GridAction]
    public virtual ActionResult ListAjax(SearchMemberModel search)
    {
        var gridModel = new GridModel<SerializableMember>();
        var data = _session.All<Member>();
        if (search != null)
        {
            if (search.Active) data = data.Where(x => x.Active);
            if (!string.IsNullOrEmpty(search.Email)) data = data.Where(x => x.Email.Contains(search.Email));
            if (!string.IsNullOrEmpty(search.FirstName)) data = data.Where(x => x.FirstName.Contains(search.FirstName));
            if (!string.IsNullOrEmpty(search.LastName)) data = data.Where(x => x.LastName.Contains(search.LastName));
            if (!string.IsNullOrEmpty(search.MemberNumber)) data = data.Where(x => x.MemberNumber.Contains(search.MemberNumber));
            if (!string.IsNullOrEmpty(search.Phone)) data = data.Where(x => x.Phone.Contains(search.Phone));
        }

        var list = new List<SerializableMember>(data.Count());
        list.AddRange(data.ToList().Select(obj => new SerializableMember(obj)));
        gridModel.Data = list;
        return View(gridModel);
    }

我可以给你我的搜索模型类:

我可以给你我的搜索模型类:

public class SearchMemberModel
{
    [LocalizedDisplayName("MemberNumber")]
    public string MemberNumber { get; set; }

    [LocalizedDisplayName("Email")]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [LocalizedDisplayName("FirstName")]
    public string FirstName { get; set; }

    [LocalizedDisplayName("LastName")]
    public string LastName { get; set; }

    [LocalizedDisplayName("Phone")]
    public string Phone { get; set; }

    [LocalizedDisplayName("ActiveOnly")]
    public bool Active { get; set; }
}

希望这能帮助到那些需要的人!


1
你的方法基本上与GlobalCompe的方法相同 - 将Javascript参数传递给重新绑定调用。我看到这种方法存在的问题是,在分页时参数会丢失。你也看到了吗? - Craig Fisher
已解决,有点。在最新的MVC扩展(Q1-2011)beta版中,这个(分页)是有问题的。 - Craig Fisher
1
这个答案比Telerik网站上大多数客户端API示例更有帮助。非常感谢! - Samuel

2
<script type="text/javascript">
    $(document).ready(function () {
        $('#apply').click(function () {
            var params = { 
                showDisabled : $('input[name=ShowDisabled]').attr('checked'), 
                showExpired : $('input[name=ShowDisabled]').attr('checked')
            };

            var grid = $('#Grid').data('tGrid');
            grid.rebind(params);
        });
    });
</script>

这里是与您的选择命令绑定的控制器动作:
[GridAction(EnableCustomBinding=true)]
public ActionResult _BindGrid(GridCommand command, string mode, int? id, bool showExpired, bool showDisabled)
{
    return View(new GridModel(GetMessageGridItems(command, mode, id,  showExpired, showDisabled)));
}

参数'command'包含排序和分页信息。注意:此解决方案适用于ajax化的网格。如果您正在进行直接发布,则仍可以使用GridCommand命令参数来维护分页/筛选/排序状态。


2
这实际上在这里有详细记录。

所以如果我理解正确,我所要做的就是将数据绑定设置如下:Html.Telerik().Grid(Model) .DataBinding(databinding => databinding.Ajax().Select("GetInvoicesInPages", "Invoices", new { startSearchDate = (string)ViewData["StartDatePicker-input"] })) .EnableCustomBinding(true)然后在客户端执行以下操作: $("#searchButton").click(function() { var grid = $("#Invoices").data('tGrid'); grid.ajaxRequest();} ); - GlobalCompe

0

这里有一种更简单的方法,在Telerix Ajax回传期间从您的表单中返回参数。

只需钩入全局$.ajaxPrefilter事件,并使用jquery将您的表单内容序列化到正在提交的URL中。这将与ASP.MVC模型绑定一起使用。

<script type="text/javascript">

$.ajaxPrefilter(function (options) {
    options.url = options.url + "&" + $("form").serialize();
});

</script>

0

这个解决方案没有在服务器端进行过滤,是吗?据我所知,您正在对已经执行的选择操作进行过滤,以针对您的数据源。 - Merritt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接