调用.ajaxRequest后,Telerik MVC Grid无法绑定

时间:2011-10-17 20:21:36

标签: asp.net-mvc telerik telerik-grid telerik-mvc

我有一些奇怪的情况正在发生。我正在尝试在自定义HTML帮助程序中构建Telerik MVC网格,该帮助程序实现了一些其他自定义功能。 (除此之外,当选择一行时,它会在网格右侧呈现一个表单。由于UI标准化,我们没有使用网格的内置编辑功能。整个要求是,对于简单列表 - 在数据库中的值表中,我们想要一个最小代码方法。在HTML中有一行,最多几行Javascript,以及繁荣,完成。)

一切正常 - 除了动态重新绑定数据。网格渲染,其选择工作,表单显示,窗体保存模糊事件。网格命中OnDataBinding事件,但之后没有任何反应。它永远不会到达OnDataBound事件,它永远不会触及网格对象本身的内部bindTobindData方法。

“足够”的代码(很多都无法揭示)因此(HTML帮助):

    public static void ListOfValuesEditorFor<TModel, TModelCollection>(this HtmlHelper<TModelCollection> htmlHelper, string gridName, string refreshAction, string refreshController, string loadItemUrl, IEnumerable<TModel> model) where TModel : class where TModelCollection : IEnumerable<TModel>
    {
        var factory = HtmlHelperExtension.Telerik<TModelCollection>(htmlHelper);
        var grid = factory.Grid(model);
        grid = grid.Name(gridName).Pageable(pager => pager.Enabled(false)).Selectable(select => select.Enabled(true)).Filterable(filter => filter.Enabled(false)).Scrollable().Sortable(sort => sort.Enabled(false));
        grid = grid.DataBinding(binding => binding.Ajax().Select(refreshAction, refreshController));
        grid = grid.ClientEvents(events =>
        {
            events.OnDataBound("Telerik.ListOfValues.OnDataBound");
            events.OnDataBinding("Telerik.ListOfValues.OnDataBinding");
            events.OnRowSelect("Telerik.ListOfValues.SelectRow");
        });

        var textControls = new List<string>();
        int idColumn = -1;
        grid = grid.Columns(columns =>
        {
            int cellCount = 0;
            foreach (var prop in typeof(TModel).GetProperties())
            {
                // Populates columns, creates text entry controls in the list, 
                // handles some other proprietary work.
                // SNIP
            }
        });

        // Container for the form
        var formDivBuilder = new TagBuilder("div");
        // Build out the form
        // SNIP

        // Render to the response
        var response = HttpContext.Current.Response;
        response.Write("<input type=\"hidden\" id=\"loadItemUrl\" value=\"" + loadItemUrl + "\" />");
        response.Write("<input type=\"hidden\" id=\"idColumnIndex\" value=\"" + idColumn.ToString() + "\" />");
        grid.Render();
        response.Write(formDivBuilder.ToString(TagRenderMode.Normal));
    }

这样称谓HTML帮助:

<% using (Html.BeginForm()) {
    Html.ListOfValuesEditorFor("JobTitleGrid", "RefreshJobTitles", "Home", "/Home/LoadJobTitle", Model);
} %>

在世界的Javascript方面,所有OnDataBound和OnDataBinding都会显示消息,表明它们已被命中。实际上,他们甚至不会使用它的代码的生产版本;他们现在正在那里进行调试。

OnSelect显示并填充表单。这种情况正确发生。

表单本身会在文本字段的onChange事件触发时更新对象。此部分经过验证可用。这是通过$ .ajax()调用完成的,该调用再次被验证起作用。

因此$ .ajax()调用成功回调:

function onSubmitComplete(responseData, callbackData) {
    // Some irrelevant junk here
    $('#JobTitleGrid').data('tGrid').ajaxRequest();
}

ajaxRequest功能的调用。在服务器上,我的网格动作起作用,返回IJobTitle对象的IList。在客户端,OnDataBinding触发,显示其消息。 OnDataBound永远不会触发,并且网格显示不会更新。

我知道这有点超出了Telerik控件通常使用方式的范围,但使用它们所需的大量代码会鼓励我的团队尽可能尝试创建可重用的实体(例如这些自定义HTML帮助程序)。对于更简单的控件(文本框,日历等),我们的自定义帮助程序始终“只是工作”。但是,网格正在呈现这个问题。

关于我们为什么永远不会绑定数据的任何想法?更重要的是,如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

在提出解决方案之后,我简要地考虑了删除这个问题 - Telerik的网格在这里只涉及最低限度。但是,当你在构建于框架之上的框架之上构建时,我知道第一手对代码进行故障排除是多么困难,框架是在框架之上进一步构建的。 :)所以希望这个答案可以帮助下一个人。

实际问题是网格操作中DAL调用的序列化异常。这对我来说似乎很奇怪,因为我使用完全相同的调用来填充Index操作中的预加载视图和GridAction的响应,但果然,如果我在Javascript中调试得足够深,我最终找到了它。没有处理异常(pro-tip:为网格实现OnError处理程序),因此客户端重新绑定失败,因为它没有要绑定的数据。

一旦我解决了序列化问题,一切都神奇地起作用了,我们需要大约20行代码来实现整个通用实体数据输入屏幕。