2010-02-02 39 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语句。

相关问题