Предоставление частичного просмотра при нажатии кнопки в ASP.NET MVC
Проблема, которую я буду описывать, очень похожа на те, которые я уже нашел (например, этот пост с почти одинаковым именем), но я надеюсь, что смогу это сделать это не дубликат.
Я создал новое приложение ASP.NET MVC 5 в Visual Studio. Затем я определил два класса моделей:
public class SearchCriterionModel
{
public string Keyword { get; set; }
}
public class SearchResultModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Затем я создал SearchController
следующим образом:
public class SearchController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DisplaySearchResults()
{
var model = new List<SearchResultModel>
{
new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
};
return PartialView("SearchResults", model);
}
}
а также представления Index.cshtml
(строго типизированные с SearchCriterionModel
как модель и шаблон Edit) и SearchResults.cshtml
как частичный вид с моделью типа IEnumerable<SearchResultModel>
(список шаблонов).
Это представление индекса:
@model WebApplication1.Models.SearchCriterionModel
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SearchCriterionModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Keyword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Keyword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='@Url.Action("DisplaySearchResults", "SearchController")'" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">
</div>
Как вы можете видеть, я добавил div
с id="searchResults"
под стандартным шаблоном и отредактировал кнопку. Я хочу отобразить частичный вид SearchResults.cshtml
в div
внизу, но только после нажатия кнопки. Мне удалось показать частичный вид там, используя @Html.Partial("SearchResults", ViewBag.MyData)
, но он отображается, когда родительский вид загружается в первый раз, и я уже установил ViewBag.MyData
в методе Index()
, чего я не хочу.
Резюме. При нажатии кнопки я получу несколько экземпляров List
из SearchResultModel
(через доступ к базе данных), а затем частичное представление должно быть отображено с использованием этих недавно полученных данных в качестве модели. Как я могу это сделать? Я уже, кажется, не сработал на первом шаге, который реагирует на нажатие кнопки с помощью вышеуказанного кода. Прямо сейчас, я перехожу к URL ~/Search/DisplaySearchResults
, но, конечно, там ничего нет и не вызывается метод кода.
В традиционной ASP.NET я бы просто добавил обработчик OnClick
на стороне сервера, установил DataSource
для сетки и покажу сетку. Но в MVC я уже не справился с этой простой задачей...
Обновление:. Изменение кнопки на @Html.ActionLink
Я могу, наконец, ввести метод контроллера. Но, естественно, поскольку он возвращает частичный вид, он отображается как содержимое всей страницы. Поэтому возникает вопрос: как сообщить частичное представление в конкретном div
на стороне клиента?
Ответы
Ответ 1
Измените кнопку на
<button id="search">Search</button>
и добавьте следующий script
var url = '@Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
var keyWord = $('#Keyword').val();
$('#searchResults').load(url, { searchText: keyWord });
})
и изменить метод контроллера, чтобы принять текст поиска
public ActionResult DisplaySearchResults(string searchText)
{
var model = // build list based on parameter searchText
return PartialView("SearchResults", model);
}
Метод jQuery .load
вызывает ваш метод контроллера, передает значение текста поиска и обновляет содержимое <div>
с частичным представлением.
Примечание: использование тега <form>
и @Html.ValidationSummary()
и @Html.ValidationMessageFor()
, вероятно, здесь не обязательно. Вы никогда не возвращаете представление Index
, поэтому ValidationSummary
не имеет смысла, и я предполагаю, что вы хотите, чтобы текст поиска null
возвращал все результаты, и в любом случае у вас нет атрибутов проверки для свойства Keyword
, поэтому существует ничего не проверять.
Edit
На основе комментариев OP, что SearchCriterionModel
будет содержать несколько свойств с атрибутами проверки, тогда подход будет включать кнопку отправки и обрабатывать формы .submit()
event
<input type="submit" value="Search" />
var url = '@Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
if (!$(this).valid()) {
return false; // prevent the ajax call if validation errors
}
var form = $(this).serialize();
$('#searchResults').load(url, form);
return false; // prevent the default submit action
})
и метод контроллера будет
public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
var model = // build list based on the properties of criteria
return PartialView("SearchResults", model);
}
Ответ 2
Итак, вот код контроллера.
public IActionResult AddURLTest()
{
return ViewComponent("AddURL");
}
Вы можете загрузить его, используя метод загрузки JQuery.
$(document).ready (function(){
$("#LoadSignIn").click(function(){
$('#UserControl').load("/Home/AddURLTest");
});
});
ссылка на исходный код