2010-02-02 42 views
1

我有一個HTML表,其中每行都有按鈕,用於切換數據庫中每行的狀態位。假設Javascript不是一個選項,那麼處理這個問題的「最佳實踐」方式是什麼?ASP.NET MVC 2:更好的方式來處理每個HTML表格行中的多個按鈕?

我目前正在處理它通過包裝中的每一行的形式這樣的:

<table> 
    <tr> 
     <td> 
      <form action="/FooArea/BarController/BazAction" id="frm0" name="frm0" method="post"> 
       <span>Item 1</span> 
       <input type="submit" value="Toggle1" name="submitButton" /> 
       <input type="submit" value="Toggle2" name="submitButton" /> 
       <input type="hidden" name="itemID" value="1" /> 
      </form> 
     </td> 
    </tr> 
    <tr> 
     <td> 
      <form action="/FooArea/BarController/BazAction" id="frm1" name="frm1" method="post"> 
       <span>Item 2</span> 
       <input type="submit" value="Toggle1" name="submitButton" /> 
       <input type="submit" value="Toggle2" name="submitButton" /> 
       <input type="hidden" name="itemID" value="2" /> 
      </form> 
     </td> 
    </tr> 
</table> 

而且POST方法看起來是這樣的:

string buttonName = Request.Form["submitButton"];  
if (!String.IsNullOrEmpty(buttonName)) 
{ 
    int itemID = Convert.ToInt32(Request.Form["itemID"]); 
    switch (buttonName) 
    { 
     case "Toggle1": 
     DoSomething(itemID); 
     break; 

     case "Toggle2": 
     DoSomethingElse(itemID); 
     break; 
    } 
} 

什麼更好的建議?在一個頁面上有50個表單很酷?我不知道,讓我知道你在這種情況下做什麼。

回答

2

正如其他幾個人所說,處理POST情況下沒有JavaScript的最佳方式是隻有必要值的小表單,並且只有一個提交按鈕。基本上,你應該做的是創建一個幫助器方法,在隱藏域和提交按鈕中創建一個必要的POST值的表單。例如,你可以使用這樣的方法:

<%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", new List<KeyValuePair<string, string>>{ new KeyValuePair<string, string>("itemId", 1), new KeyValuePair("action", "option1") }); %> 

它看起來很囉嗦,但我試圖使它儘可能通用。你或許可以在控制器創建List<KeyValuePair<string, string>>當渲染視圖,所以你只需要調用一些

<%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", Model.Values) %> 

在處理後的操作方法,綁定到發佈的FormCollection和檢索的值itemIdaction來確定要做什麼,而不是檢查Request.Form值。

輔助方法的實現可能是這樣的:

public static string PostLink(this HtmlHelper helper, string postAction, string submitText, IEnumerable<KeyValuePair<string, string>> postValues) 
{ 
    var form = new TagBuilder("form"); 

    // Setup basic properties like method, action 
    form.Attributes.Add("method", "post"); 
    form.Attributes.Add("action", postAction); 

    // Instantiate a stringbuilder for the inner html of the form 
    var innerHtml = new StringBuilder(); 

    // Create and append hidden fields for the post values 
    foreach(var value in postValues) 
    { 
     var hidden = new TagBuilder("input"); 
     hidden.Attributes.Add("type", "hidden"); 
     hidden.Attributes.Add("name", value.Key); 
     hidden.Attributes.Add("value", value.Value); 
     innerHtml.Append(hidden.ToString(TagRenderMode.SelfClosing)); 
    } 

    // Create the submit button 
    var submit = new TagBuilder("input"); 
    submit.Attributes.Add("type", "submit"); 
    submit.Attributes.Add("value", submitText); 
    // Append it to the stringbuilder 
    innerHtml.Append(submit.ToString(TagRenderMode.SelfClosing)); 

    // Set the InnerHtml property of the form, and return it 
    form.InnerHtml = innerHtml.ToString(); 
    return form.ToString(TagRenderMode.Normal); 
} 
+0

創建一個帶有隱藏字段的HTML助手錶單是一個非常有趣的方法。我喜歡。特別是因爲我們可以通過來自控制器的隱藏輸入集並簡化整個交易。 :)感謝分享! – 2010-02-02 18:15:33

0

這似乎是一些JQuery和Ajax功能的主要情況。但是,如果JavaScript不是一個選項,那麼我認爲將每個包裝在一個表單中可能是最簡單的解決方案。

+0

謝謝,是啊,我試圖找出是否有我忽視的東西。我不相信這是最優雅的解決方案,但如果是這樣做的話,那麼嘿...;) – 2010-02-02 15:54:54

0

當我需要做這樣的事情時,我的行事方式與您在此做的幾乎一樣。在一個視圖中有多種形式是沒有問題的。就像在一個視圖中有多個鏈接(但他們使用POST而不是GET)。我猜很多.net開發人員認爲它的錯誤是因爲webforms只有一個表單標籤。在你的情況下,我甚至會爲每個提交按鈕創建更多的表單,因爲他們似乎做了不同的事情。我認爲必須檢查控制器中按鈕的名稱是否是代碼異味。如果他們做了類似激活/停用的事情,你應該將其作爲布爾或其他東西發佈,並將這兩個表單發佈到同一個動作。

+0

你是絕對正確的,我已經習慣了每頁1個表單,所以看到50一個讓我感到震驚。感謝您的反饋Mattias。 – 2010-02-02 15:59:14

+0

P.S.出於您指出的原因,我還編輯了Activate/Disable中的值。我看到一個......嘿嘿。 – 2010-02-02 16:01:25

+1

是的,我可以理解。當我從webforms遷移時,我也有同樣的感受。即使你打算用javascript和ajax來做這件事,我也可能會添加這些表單。這樣,當瀏覽器中禁用了JavaScript,並且它非常容易使用某些jQuery ajax表單插件時,它將起作用。 – 2010-02-02 16:10:06

0

我想技術上這是最好的方法。從可用性的角度來看,你可以質疑這是否是最好的方法。列表中的超過20項可能會讓人感到困惑。但當然,我不知道你在編程:)

我同意Mattias關於爲激活和停用按鈕創建不同的動作。這樣你可以避免使用switch語句。

相關問題