Telerik MVC Grid не может связаться после вызова .ajaxRequest - PullRequest
0 голосов
/ 18 октября 2011

У меня происходит странная ситуация. Я пытаюсь построить сетку Telerik MVC в пользовательском помощнике HTML, который реализует некоторые другие пользовательские функции. (Среди прочего, он отображает форму справа от сетки при выделении строки. Мы не используем встроенные функции редактирования сетки из-за стандартизации пользовательского интерфейса. Единственное требование заключается в том, что для простого списка - таблиц значений в базе данных, мы хотели бы использовать подход с минимальным кодом. Одна строка в HTML, несколько строк в Javascript максимум, и бум, готово.)

Все работает, кроме динамического связывания данных. Сетка рендерится, ее выбор работает, форма отображается, форма сохраняется при размытии. Сетка попадает в событие OnDataBinding, но после этого ничего не происходит. Он никогда не попадает в событие OnDataBound и никогда не попадает во внутренние методы bindTo или bindData самого объекта сетки.

«Достаточно» кода (большая его часть не может быть раскрыта), таким образом (HTML helper):

    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 функций. На сервере мое действие сетки работает, возвращая IList объектов IJobTitle. На клиенте OnDataBinding срабатывает, отображая свое сообщение. OnDataBound никогда не срабатывает, и отображение сетки не обновляется.

Я знаю, что это несколько выходит за рамки обычного использования элементов управления Telerik, но огромное количество кода, необходимого для их использования, побуждает мою команду пытаться создавать повторяющиеся объекты (такие как эти пользовательские помощники HTML) везде, где это возможно. Для более простых элементов управления (текстовые поля, календари и т. Д.) Наши пользовательские помощники всегда «просто работали». Сетка, тем не менее, представляет эту проблему.

Есть идеи, почему мы никогда не привязываем данные? Что еще более важно, как это исправить?

1 Ответ

0 голосов
/ 20 октября 2011

После того, как я пришел к решению, я кратко подумал об удалении вопроса - сетка Telerik здесь задействована минимально. Тем не менее, я знаю из первых рук, как сложно устранять неполадки кода, когда вы строите поверх фреймворков, которые построены поверх фреймворков, которые в дальнейшем строятся поверх фреймворков. :) Надеюсь, этот ответ поможет следующему парню.

Фактическая проблема оказалась исключением сериализации из вызова DAL в действии сетки. Это показалось мне странным, так как я использовал один и тот же вызов для заполнения предварительно загруженного представления в действии Index и ответа от GridAction, но, конечно же, если я достаточно глубоко отладил в Javascript, я в конце концов нашел его , Исключение не было обработано (pro-tip: реализовать обработчик OnError для сетки), и, таким образом, сбой привязки на стороне клиента завершился неудачей, поскольку у него не было данных для привязки.

Как только я решил проблему с сериализацией, все просто волшебным образом сработало, и у нас было около 20 строк кода для реализации всего экрана ввода данных общего объекта.

...