#asp.net-mvc-4 #partial-views
#asp.net-mvc-4 #частичные представления
Вопрос:
У меня есть частичное представление, которое включено в мой _Layout.cshtml. Это частичное представление содержит выпадающий список, который заполняется правильно.
Когда пользователь выбирает значение, я хочу, чтобы это значение было доступно везде. Поэтому я попытался установить его в своих данных сеанса.
Это работает нормально.
Частичный просмотр:
@model MyModel
@using (Ajax.BeginForm("MySelection", "Home", new AjaxOptions()))
{
var optionList = new SelectList(Model.Options, "Key", "Value");
@Html.DropDownListFor(model => model.SelectedOption, optionList,
"--Select--", new { onchange = "this.form.submit(); return false;" })
}
И, конечно же,
[HttpPost]
public PartialViewResult MySelection(MyModel model)
{
Session["MySelection"] = model.SelectedOption;
return PartialView("_MyPartial", model);
}
Получает попадание, устанавливает данные сеанса и возвращает частичное представление.
Однако… это частичное представление — все, что я вижу! Вместо того, чтобы оставаться на той же странице, отображается только частичное представление.
Я бегаю по кругу, пытаясь выяснить, как я могу просто, просто сохранить выбранное значение в своих данных сеанса, мне не нужно возвращать представление, частичное представление или что-либо еще, мне не нужно перезагружать данные, перезагружать страницу, перенаправлять куда угодно.
Что такое (несомненно, очень просто!) способ получить выбранный параметр в моих данных сеанса?
Как предположил Эхсан Саджад, убедившись, что все остальное на месте, использование (скрытой) кнопки для отправки формы выполнит ajax-запрос, тогда как this.form.submit в обработчике onchange этого не делает!
Короче говоря, теперь у меня есть:
@model MyModel
@using (Ajax.BeginForm("MySelection", "Home", new AjaxOptions()))
{
var optionList = new SelectList(Model.Options, "Key", "Value");
@Html.DropDownListFor(model => model.SelectedOption, optionList,
"--Select--", new { onchange = "submitButton.click();" })
<input type="submit" id="submitButton" class="hidden-button"/>
}
и
[HttpPost]
public void MySelection(MyModel model)
{
Session["MySelection"] = model.SelectedOption;
}
И это работает как шарм.
Ответ №1:
Если вы не хотите ничего возвращать, верните EmptyResult:
[HttpPost]
public ActionResult MySelection(MyModel model)
{
Session["MySelection"] = model.SelectedOption;
return new EmptyResult();
}
другим способом может быть использование AjaxOptions, а также создание контейнера div в основном представлении:
<div id="container">
</div>
@using (Ajax.BeginForm("MySelection", "Home", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "conatainer" }))
{
var optionList = new SelectList(Model.Options, "Key", "Value");
@Html.DropDownListFor(model => model.SelectedOption, optionList,
"--Select--", new { onchange = "this.form.submit(); return false;" })
}
и вы можете возвращать пустое содержимое следующим образом:
[HttpPost]
public ActionResult MySelection(MyModel model)
{
Session["MySelection"] = model.SelectedOption;
return Content("");
}
ОБНОВЛЕНО:
Вам нужно добавить скрытую кнопку отправки и при изменении индекса в раскрывающемся списке программно вызвать ее щелчок, так как программная отправка формы не запускает исходную отправку, поэтому форма публикуется, не публикуется через ajax, и происходит полная обратная отправка.
Комментарии:
1. Если я ничего не возвращаю, я ничего не вижу. Буквально. Пустая страница. Это моя главная проблема. Данные попадают на контроллер, но моя страница перенаправляется на /Home/MySelection . Это либо только мое частичное представление, либо, если я ничего не возвращаю, пустая страница, или, если я возвращаю строку, значение этой строки.
2. да, я включил их, точно так же, как в вашем примере, за исключением того, что я исправил ‘conatainer’.
3. в этом случае он обновил только этот контейнер div, а не весь div, является ли jquery ненавязчивым.ajax включен в обратную запись вашей страницы или частичную обратную запись?
4. jquery-ненавязчивый.ajax включен в BundleConfig: bundles. Добавить(новый ScriptBundle(«~/bundles/jqueryval»). Включить(«~/Scripts/jquery.unobtrusive*»). Включение его явно, на мой взгляд, тоже не помогло. Он не обновил только div, он «обновил» всю страницу : (
5. это означает, что ваша форма публикуется через ajax, и она выполняет отправку обратно
Ответ №2:
Представление должно будет что-то сделать с возвращенными данными. И поскольку вы не сказали ему, что с ним делать, он прибегает к поведению по умолчанию, заменяя текущую цель возвращаемым значением.
Как насчет того onChange
, чтобы событие dropdown
вызова функции выглядело следующим образом:
function SaveMySelection(paramsToPassToServer) {
var methodParam = JSON.stringify(paramsToPassToServer);
var methodUrl = '@Url.Action("MySelection", "Home")';
var requestType = //GET or POST;
var successMethod = function (srvResponse) {
//You can do some parsing of the returned json in case you want to
//or just ignore the returned value
}
$.ajax({
type: requestType,
url: methodUrl,
data: requestType == "POST" ? methodParam : decodeURIComponent($.parseJSON(methodParam)),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: false,
success: successMethod,
error: FunctionToHandleOnError
});
}
Javascript не совсем чистый, поскольку я быстро перенял «параметризованную» версию, которую мы внедрили, но это должно дать вам общее представление.
Комментарии:
1. Я пробовал это раньше, но мой код не попал — теперь я помещаю его в начало своего представления, и он работает… вроде того. По какой-то причине, когда я использую форму отправки, в моей модели выбранная опция заполнена правильно, но с помощью этой функции я получаю модель без выбранной опции (она равна нулю). Пробовал также с типом данных text, не повезло.
2. для работы с этим кодом необходимо изменить возвращаемый метод на JSon.
3. Я никогда не получал никаких данных в метод, независимо от его возвращаемого типа. В любом случае, мне ничего не нужно возвращать, а скрытая кнопка отправки — это всего лишь одна дополнительная строка кода. В любом случае спасибо за усилия!