MVC, выпадающий список для в partialview, onchange должен хранить выбранное значение _вместе_

#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. Я никогда не получал никаких данных в метод, независимо от его возвращаемого типа. В любом случае, мне ничего не нужно возвращать, а скрытая кнопка отправки — это всего лишь одна дополнительная строка кода. В любом случае спасибо за усилия!