在MVC 3 Razor视图中,当布局需要嵌套表单时,如何发布到不同的操作



使用我的一些MVC 3 Razor视图时,我发现需要嵌套表单,这是不可能的(在HTML中是不允许的)。

有一个表单,针对特定的操作,它包含一个表。但在一些/all/one_paspecial表行上,我需要针对一个单独的操作。例如:

@using (Html.BeginForm("EditPersons"))
{
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
@for (int i=0; i < Model.Persons.Count; i++)
{
<tr>
<td>@Html.TextBox(...)</td>
<td>@Html.TextBox(...)</td>
</tr>
}
<tr>
<td></td>
<td>
@using (Html.BeginForm("AddPerson")
{
<input type="submit" value="Add person" />
}
</td>
</tr>
</table>
}

现在,我显然可以将"Add person"按钮放在整个表的下面,但我该如何使它与第二列表对齐呢?

此外,我可以让"添加人员"按钮在一个隐藏的字段中放入一些"命令",并让EditPersons操作检查它是否应该添加人员或为现有人员保存更新的数据,但我觉得这会在一定程度上打破单目的操作的范式(而不是可怕的老式ASP"发布到自己身上"表单)。

那么,我该如何解决这个问题呢?

嗨,我不明白您如何需要2个表单,以及为什么需要使用服务器端技术。

我相信有人能够找到使用asp.net mvc技术的解决方案,但就我而言,javascript会轻而易举地做到这一点。因此,您希望能够在提交整个表单之前向服务器发送一些值,或者您可能希望表单的各个部分以不同的方式工作,而不是作为一个整体。没关系。无论哪种方式,javascript都是您的语言,请考虑对代码的这些更改(使用jQuery):

@using (Html.BeginForm("EditPersons"))
{
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
@for (int i=0; i < Model.Persons.Count; i++)
{
<tr>
<td>@Html.TextBox(...)</td>
<td>@Html.TextBox(...)</td>
</tr>
}
<tr>
<td><input type="text" id="field" name="field"/></td>
<td>
<input type="button" id="btnAddPerson" value="Add person" />
</td>
</tr>
<tr><td colspan="2"><input type="submit" value="send the whole thing" /></td></tr>
}
<script>
$(document).ready(function(){
$("#btnAddPerson").click(function(event){
event.stopPropagation();
$.post("/actionTohandle/addperson", { person : $("#field").val()}, function(data){
//do something with the result
})
})
})
</script>

如果单击添加人员按钮,它将向服务器端发送POST请求,FormCollection对象将只有一个键,即collection["field"]。我正在调用的操作(AddPerson)在ActionToHandleController上。另一方面,如果你点击提交按钮,你会调用PersonsController上的EditPersons。因此,在2个不同的位置(控制器)上执行2个不同操作。同样的形式。这个例子只是冰山一角。这是ASP.NET MVC的一个伟大功能—您有更多的灵活性,并且不是所有事情都必须作为服务器端脚本处理。

我目前正在做类似的事情。我将要采取的操作存储在输入元素中。

<input type="submit" value="Add person" data-action"/AddPerson">

然后,通过订阅点击或表单提交,使用.data().将表单Action=""更改为数据操作

FYI,在表中放置表单标记(即围绕tr标记)是不合法的HTML。它可以在一些(大多数?)浏览器中工作,但不能保证它会工作,也不能保证移动浏览器会支持它

那么,问你如何做一些无效的事情来避免做其他同样无效的事情,到底有什么意义呢?

正确的方法是将表包装在一个表单中。然后,在每一行使用提交按钮,但给每一行一个稍微不同的id,例如"submit_1",然后计算出哪一行按钮被哪个按钮点击了,哪个按钮出现在发布的值中。

其他的可能性是有JavaScript,当你点击按钮时会执行:

<input type="button" onclick="SubmitMyForm(15)" /> 

如果您有一个名为SubmitMyForm的方法,它接受行号的参数(或者您想要使用的任何其他标识符,也许您可以使用jquery提取数据属性值来标识行)。

最后,在表的底部,您可以调用一个不同的方法,例如"AddPerson",它将修改表单的动作属性,然后调用form.submit()并将其发布到不同的动作。尽管说实话,在大多数情况下,你不需要为此发帖。。你可以使用一个重定向到新页面的链接。

在任何情况下,即使在表单中包装tr是合法的(事实并非如此),也不需要嵌套表单(无效)。

不清楚您试图通过这些表单实现什么。。。我想说应该只有一种形式:编辑或创建——哪一种形式应该决定你的服务器(或客户端)逻辑。然而,如果您确实需要两个"嵌套"表单,可以考虑使用jquery.ajax方法来调用操作

最新更新