我正在通过将旧的Web窗体转换为MVC来学习MVC。页面非常简单,只有几个文本框,一个提交按钮和一个网格。我想要在页面加载时没有网格的类似功能,并且在提交发生后,网格出现。我遇到的问题是我看到的所有示例都包含页面加载时的数据。
这是我的观点
<h2>Search Craigslist</h2>
@using (Html.BeginForm())
{
<p>
Enter Search Criteria:<br />
@Html.TextBox("Criteria", null, new { @style = "width: 450" })
@Html.DropDownList("DropDownValues")
Days:
@Html.TextBox("Days")
<br />
<input type="submit" value="Submit" />
</p>
}
@Html.Partial("~/Views/Search/_Search.cshtml")
和部分
@model IEnumerable<CraigsListSearch.MVC.Models.SearchModel>
@{
Layout = null;
}
<table cellspacing="0" border="1" style="border-collapse:collapse;">
<tr>
<th>
@Html.DisplayNameFor(model => model.Location)
</th>
<th>
Link
</th>
<th>
@Html.DisplayNameFor(model => model.DateSubmitted)
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Location)
</td>
<td>
@Html.Hyperlink(Html.DisplayFor(modelItem => item.URL).ToString(), Html.DisplayFor(modelItem => item.Title).ToString())
</td>
<td>
@Html.DisplayFor(modelItem => item.DateSubmitted)
</td>
</tr>
}
最后是控制器
public class SearchController : Controller
{
[HttpGet]
//public ViewResult Index(string DropDownValues, string Criteria, string Days)
public ViewResult Index()
{
Populate();
Session["list"] = SearchModel.GetQuickList();
return View(new List<SearchModel>());
}
[HttpPost]
public ViewResult Index(string DropDownValues, string Criteria, string Days)
{
Populate();
Criteria = Server.UrlPathEncode(Criteria).Replace(",", "%2c");
List<Location> list = (List<Location>)(Session["list"]);
List<SearchModel> results = SearchModel.Search(Criteria, Days, DropDownValues, list.Take(5).ToList());
return View(results);
}
private void Populate()
{
List<DropDownModel> ddlList = DropDownModel.GetDropdowns();
ViewBag.DropDownValues = (from a in ddlList
select new SelectListItem
{
Text = a.Text,
Value = a.Value
}).ToList();
}
}
我正在寻找的是让部分只被叫做#34;在POST上。这是否可以轻松完成?如果需要其他信息,请告诉我。
谢谢!
答案 0 :(得分:1)
有几种方法可以解决这个问题。
一种选择是使用AJAX。当用户单击该按钮时,对控制器进行AJAX调用,让控制器呈现部分并返回HTML,然后将其注入页面DOM。
另一种选择是添加&#34; DisplayGrid&#34;你的模特的财产。首次渲染视图时,将其设置为false,然后在帖子后将其设置为true。
我想说的一点是,从Post动作渲染视图并不是一个好主意。如果用户在浏览器中点击“刷新”,它将再次发布,为用户提供令人讨厌的丑陋对话,告诉他们他们将要向服务器发送数据。通常,您应该使用Post-Redirect-Get模式,用户发布,重定向,然后在浏览器中使用get重新呈现。如果你使用AJAX方法,这一切都没有实际意义,因为你永远不会将整个表单发布回控制器动作。如果您继续使用完整帖子,则HttpPost版本的Index应返回RedirectToAction结果,将用户返回到获取版本的索引。您可以使用TempData在两个操作之间进行通信,例如:
[HttpGet]
public ActionResult Index()
{
if( TempData.ContainsKey( "DisplayGrid" )
{
// Use the other values from TempData to populate the model with the grid data
myModel.DisplayGrid = (bool)TempData["DisplayGrid"];
}
}
[HttpPost]
public ActionResult Index( string dropDownValues, string criteria, string days )
{
TempData["DisplayGrid"] = true;
TempData["DropDownValues"] = dropDownValues;
TempData["Criteria"] = criteria;
TempData["Days"] = days;
return RedirectToAction( "Index" );
}
答案 1 :(得分:0)
您应该通过模型(或ViewBag
)传递您需要的任何信息。
由于您已经有了Model
如何使用的示例,因此您可以使用ViewBag
@if(ViewBag.RenderSearch)
{
@Html.Partial("~/Views/Search/_Search.cshtml")
}
并设置RenderSearch
特定操作:
public ViewResult Index(string DropDownValues...
{
....
ViewBag.RenderSearch = true;
使用模型只需为模型添加属性(您需要将其设置为自定义类而不仅仅是List
)并检查该标志。
答案 2 :(得分:0)
试试这个,Ajax只替换GridDiv
<h2>Search Craigslist</h2>
using (Ajax.BeginForm("BindGridAction", "Contoller",new AjaxOptions { UpdateTargetId = "GridDiv" }))
{
<p>
Enter Search Criteria:<br />
@Html.TextBox("Criteria", null, new { @style = "width: 450" })
@Html.DropDownList("DropDownValues")
Days:
@Html.TextBox("Days")
<br />
<input type="submit" value="Submit" />
</p>
}
<div id="GridDiv">
@Html.Partial("~/Views/Search/_Search.cshtml")
</div>
在控制器中绑定部分视图
public PartialViewResult BindGridAction()
{
// your model coding
return PartialView("~/Views/Search/_Search.cshtml", model);
}