我对MVC很新。 我正在尝试创建一个页面,允许用户在同一页面上执行以下操作:
Add
按钮应更新表格)Delete
按钮应更新表格)一个简单的例子看起来像这样但我实际上在一个页面上有两个列表(费用和成本):
实现这一目标的最佳方法是什么? 我应该使用看起来像这样的Dylan Beattie's method posted here吗?
public ActionResult MyAction(string submitButton, MyViewModel form)
{
switch (submitButton)
{
case "AddFee":
return (AddFee(form));
case "AddCost":
return (AddCost(form));
case "RemoveFee":
return (RemoveFee(form));
case "RemoveCost":
return (RemoveCost(form));
}
}
public ActionResult AddFee(MyViewModel form)
{
Fee newFee = ....; // Get entered data from `form`
_repository.InsertFee(newFee);
return View("Create"); //Back to the original page
}
或者是否有任何其他推荐的方法来处理此问题,例如使用JavaScript?
答案 0 :(得分:1)
您可以将表创建为部分视图,然后通过ajax重新呈现。
将部分视图包装在div中并将表单包装在@using(Ajax.BeginForm(....并且定位包装器div)中.ajax请求所针对的控制器操作将需要返回部分视图。
这是一个简单的例子
public class HomeController : Controller
{
public ActionResult Index()
{
MYvm vm = new MYvm() { id = 1, name = "This is my View Model" };
return View(vm);
}
public ActionResult DA(MYvm vm)
{
vm.name = "CHANGED";
return PartialView("Part", vm);
}
查看:
@model MvcApplication1.Controllers.HomeController.MYvm
@{
ViewBag.Title = "Home Page";
}
@using (Ajax.BeginForm("DA", "Home", new AjaxOptions() { UpdateTargetId = "cont", HttpMethod = "Get" }))
{
<div>
Id: @Html.EditorFor(model => model.id)
</div>
<div>
Name: @Html.EditorFor(model => model.name)
</div>
<input type="submit" value="SubmitForm" />
}
<div id="cont">
@{Html.RenderPartial("part", Model);}
</div>
部分视图
@model MvcApplication1.Controllers.HomeController.MYvm
@{
ViewBag.Title = "part";
}
<h2>part</h2>
@Model.name
答案 1 :(得分:1)
我应该使用[之前的回答]
没有。这个答案是针对一个不同的场景,其中一个表格有一个带有两个提交按钮的表单,这两个按钮想要做两个不同的动作(并且甚至不能接受该问题的答案)。
您的示例屏幕截图表明,某些javascript / jquery和ajax可以彻底解决问题。
当你是MVC的新手时,尽量保持相对简单。将页面分成不同的部分:
编辑/列表独立工作,应该以可以放在任何其他页面上的方式编写 - 页面只是包含它们并且没有做其他事情(显然你的真实页面将包含更多,但也将这些部分添加为单独的组件。
1为列表创建操作并编辑返回部分视图的表单 - 只包含该视图所需的部分(自包含)
控制器:
[HttpGet]
public ActionResult AddCost()
{
var model = new Cost();
return PartialView(model);
}
[HttpPost]
public void AddCost(Cost model)
{
if (ModelState.IsValid) {
db.SaveCost(model);...
}
}
表单Views / Home / AddCost.cshtml:
@using (Ajax.BeginForm(...
{
<div class='editor-label'>@Html.LabelFor(model=>model.Description)</div>
...etc...
}
我将让您设置Ajax.BeginForm
属性。但请确保成功通话reloadCostList()
(见下文)
控制器
public ActionResult CostList()
{
var model = db.loadCosts(); ...
return PartialView(model);
}
list,Views / Home / CostList.cshtml
@model IEnumerable<ViewModels.Cost>
<table>
<thead>
<tr>
<th>Cost Description</th>
...
<tbody>
@foreach (var cost in Model.Costs)
{
<tr data-id='@cost.Id'>
<td>@Html.DisplayFor(x=>cost.Description)</td>
...
<td><a href='#' class='remove-button'>Remove</a></td>
}
...
2使用占位符为表单创建主页的操作+视图,并调用列表partial-action,例如:
<div id="body">
<div id="formWrapper">
@Html.Action("AddCost")
</div>
<div id="listWrapper">
@Html.Action("ListView")
</div>
</div>
如果你已经加载了页面的数据,你可以将它直接传递给部分,但是没有必要:
@Html.Partial("ListView", Model.Costs)
这允许您通过ajax调用刷新列表,如:
function reloadCostList() {
$(".listWrapper").load("Home/CostList");
}
(理想情况下,$ .ajax并添加一些花哨的UI来表示加载)
3向控制器添加删除操作
[HttpPost]
public void RemoveCost(int id)
{
}
4连接删除链接
$(function() {
$(".remove-button").click(function() {
var id = $(this).closest("tr").attr("id");
$.post("/Home/RemoveCost/" + id, null, function() {
$(".listWrapper").load("Home/CostList");
// or reloadCostList(); from above
// or:
//$(".listWrapper tr[id=" + id + "]").hide();
});
});
}
而不是重新加载整个列表,你可以删除该行(添加一些奇特的UI,如淡出...)