2017-04-06 70 views
0

我有一個Kendo UI ASP.NET MVC網格,帶有作爲窗體一部分提交的CRUD操作。在下面的代碼片段中,我試圖顯示帶有內聯可編輯組合框(綁定到用戶名和ID)的列,該列顯示用戶的名稱,但具有用戶ID的值。防止ClientTemplate覆蓋GridTemplate中的EditorTemplate

提交形成正常,但顯示的用戶ID,而不是名稱:

columns.ForeignKey(p => p.UserId, (System.Collections.IEnumerable)ViewBag.Users, "SystemUserId", "Name").Title("User").EditorTemplateName("ComboBoxInForm").Visible(true).ClientTemplate("#= UserId #" + 
"<input type='hidden' name='Users[#= index(data) #].UserId' value='#= UserId #' />" 
); 

ComboBoxInForm EditorTemplate:

@model object 
@(
Html.Kendo().ComboBoxFor(m => m) 
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"]) 
) 

如果我刪除,它提供的表單輸入標籤ClientTemplate,用戶的名字就是顯示的內容,而不是用戶ID的值,這正是我想要的。但是,我需要批量提交它作爲表單的一部分,所以我無法刪除表單輸入標記。

未能提交表單(沒有輸入標籤),但正確地顯示用戶名稱,而不是標識:

columns.ForeignKey(p => p.UserId, (System.Collections.IEnumerable)ViewBag.Users, "SystemUserId", "Name").Title("User").EditorTemplateName("ComboBoxInForm").Visible(true); 

我可以使用哪些解決這兩方面的要求結合起來,使網格列顯示器名稱(但帶有ID的值),並提供表單輸入標籤?

回答

1

首先,在ClientTemplate未覆蓋EditorTemplate ...

的ClientTemplate基本上是顯示模板和EditorTemplate是,好了,編輯模板。

所以,你想要的是ClientTemplate要做的是顯示與UserId關聯的名稱

如果你想保持網格的方式(使用ForeignKey和隱藏字段),那麼你需要添加一個「映射」函數,將由combobox選擇的UserId映射到關聯的名稱。

你可以做到這一點,像這樣:

剃刀:

.ClientTemplate("#= mapIdToName(UserId) #" + 
    "<input type='hidden' name='Users[#= index(data) #].UserId' value='#= UserId #' />"); 

的Javascript:

function mapIdToName(id) { 
    var grid = $("#grid").getKendoGrid(), 
     users = grid.options.columns[0].values, 
     name; 

    for (var i = 0; i < users.length; i++) { 
     if (users[i].value == id) { 
      name = users[i].text; 
      break; 
     } 
    } 

    return name; 
} 

它使用的Id-名稱數組,你已經有(通過grid.options。這是由ForeignKey()方法創建的。

替代解決方案 。 。 。 。 。 不過,還有其他方法可以實現你想要的。

一種方法是不使用ForeignKey,而是將列綁定到包含ID和名稱的對象,更具體的EditorTemplate綁定到與ForeignKey()相同的集合。這不需要映射功能,即。E:

剃刀:

columns.Bound(x => x.User) 
    .ClientTemplate("#= User.Name #" + 
    "<input type='hidden' name='Users[#= index(data) #].UserId' value='#= UserId #' />"); 

EditorTemplate:

@model object 
@(
Html.Kendo().ComboBoxFor(m => m) 
.DataValueField("SystemUserId") 
    .DataTextField("Name") 
    .BindTo((System.Collections.IEnumerable)ViewBag.Users) 
) 

的缺點隱藏輸入法,你必須電網限制在較小的行數,因爲該技術將只能夠發佈單頁的價值數據,因爲第2,3頁等數據沒有呈現,因此在表單中沒有隱藏輸入以包含在帖子中。

第三種方式(這是我做事情的方式)是根本不使用隱藏的輸入。 相反,我用ajax調用手動發佈數據,首先將「主要」表單數據(不是網格數據)序列化到對象中(如果使用kendo MVVM,這非常容易),然後將修改後的網格數據與形成數據(使用擴展),然後發佈結果組合對象。

我使用這種技術的一個變體序列化網格數據:

這樣做的好處是,它支持更大的數據集,因爲它可以使用網格尋呼機制和(這是主要的原因,我喜歡這種技術)通過在單個請求中提交表單/標題/父數據和所有網格/子數據(新/更新/刪除),您可以在服務器上同時處理所有數據,從而更好地驗證數據的整個「圖片」以及允許更新發生在單個事務支架中。

0

另一個答案from the Telerik forums

此行爲的原因是因爲ForeignKey構建器確實提供了與內置功能相關的與數字值相關聯的文本。在引擎蓋下,該列被綁定到僅包含數字值的字段。爲了在客戶端模板中顯示文本表示,應該編寫一些自定義邏輯。我想就如何實現這一目標的情況下,這可能是爲別人誰面臨同樣的困難有幫助的一些指導原則:

  1. 輸入元素的值可以被定義爲功能 接受實際字段的值作爲第一參數和字段名稱 (靜態文本)作爲第二個參數。
  2. Telerik MVC包裝渲染 初始化Kendo UI小部件所需的HTML和JavaScript。每個 外鍵列都是存儲在 columns.values中的鍵 - 值對的簡單數組。
  3. 這裏是一個函數體的一些意見,應該幫助你 說明找到那些特定號碼(當前字段值)相關的columns.values 文本的一個簡單的想法:

    功能textValue( value,fieldName){ //$("#gridNameId").data("kendoGrid").options.columns包含網格配置中定義的列 //遍歷數組並檢查每列的.field值找到與字段名稱參數(第二個參數)相同名稱的列字段//定義爲「外鍵」的每列都具有值數組。它包含組合框中顯示的每個值的鍵值對。 //返回具有相同值的第一第一個參數(值)相關聯的文本值 //返回與值 }

    ClientTemplate( 「#=#的ProductID」 + 「」

相關聯的文本