2011-10-17 28 views
0

我有一些奇怪的情況正在進行。我正在試圖在一個自定義的HTML幫助器中構建一個Telerik MVC網格,該幫助器實現了一些其他的自定義功能。 (其中,當選中某行時,它會在網格右側顯示一個表單)由於UI標準化,我們沒有使用網格的內置編輯功能,整個要求是,對於簡單的列表 - 我們想要一個最小代碼的方法,HTML中的一行,最多幾行Javascript,以及繁榮,完成)。Telerik MVC Grid在調用.ajaxRequest後無法綁定

一切正常 - 除了重新綁定數據動態。網格渲染,選擇工作,表單顯示,表單保存在模糊事件中。網格擊中了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()調用來完成的,該調用再次被驗證可以運行。

從$阿賈克斯()調用的成功回調是這樣的:

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

的呼叫ajaxRequest功能。在服務器上,我的網格動作函數返回IJobTitle對象的IList。在客戶端,OnDataBinding觸發,顯示其消息。 OnDataBound永遠不會觸發,並且網格顯示不會更新。

我知道這有點超出了Telerik控件通常使用的範圍,但使用它們所需的大量代碼鼓勵我的團隊嘗試創建可重用的實體(例如這些自定義HTML助手),只要有可能。對於更簡單的控件(文本框,日曆等),我們的自定義助手總是「只是工作」。然而,電網正在呈現這個問題。

關於爲什麼我們永遠不能綁定數據的任何想法?更重要的是,如何解決這個問題?

回答

0

在提出解決方案之後,我簡要考慮刪除問題 - Telerik的網格僅在這裏涉及最少。但是,我知道在框架之上構建基於框架的框架之上的代碼進行故障排除是非常困難的,這些框架構建在框架的基礎之上。 :)所以希望這個答案能夠幫助下一個傢伙。

實際問題原來是來自網格操作中DAL調用的序列化異常。對我來說這似乎很奇怪,因爲我使用了完全相同的調用來填充Index操作中的預加載視圖和GridAction的響應,但是果然,如果我深入調試Javascript,我最終發現它。沒有處理異常(pro-tip:爲網格實現一個OnError處理程序),因此客戶端重新綁定失敗,因爲它沒有要綁定的數據。

一旦我解決了序列化問題,一切都變得神奇地工作了,而我們實現了大約20行代碼來實現整個通用實體數據輸入屏幕。