Подтвердить что ты не робот

Предоставление частичного просмотра при нажатии кнопки в 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 на стороне клиента?

4b9b3361

Ответ 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");
    });
});

ссылка на исходный код