Заменить частичное представление после действия в ASP.Net MVC

Я все еще новичок в ASP.NET MVC и задаюсь вопросом, как добиться следующего: в обычном представлении как части моей главной страницы я создаю различное количество частичных представлений с циклом, каждое из которых представляет элемент, который пользователь должен иметь возможность проголосовать за. После нажатия кнопки голосования рейтинг будет отправлен в базу данных, а затем конкретный частичный вид, на который нажал пользователь, будет заменен тем же самым видом, но с некоторыми измененными визуальными свойствами. Какова наилучшая практика для достижения этого?

Вот как я начал: 1. Я определил частичное представление с помощью предложения if, различающего внешний вид в зависимости от флага в конкретной модели представления. Следовательно, если флаг положительный, элементы управления голосованием отображаются, если отрицательный — нет.

  1. Я назначил Url.Action(..) кнопкам голосования, которые запускают метод контроллера. В этом методе новый рейтинг добавляется в базу данных.

  2. В методе контроллера я возвращаю PartialView с обновленной ViewModel. К СОЖАЛЕНИЮ, заменяется весь вид, а не только частичный вид.

Любые предложения, как решить эту конкретную проблему или как достичь всего этого, будут высоко оценены.

Большое спасибо, Крис


person Chris    schedule 12.09.2011    source источник
comment
Ajax.BeginForm!   -  person bzlm    schedule 12.09.2011


Ответы (2)


Тривиальное (но, безусловно, правильное и полезное) решение вашей проблемы - помощник Ajax.BeginForm() для голосования. Таким образом, вы изменяете свое голосование на вызовы ajax и можете легко указать, что результат, возвращенный этим вызовом (из вашего действия голосования, которое вернет частичный просмотр только с 1 измененным элементом), будет использоваться для замены старого контента (например, один конкретный div, содержащий старый элемент перед голосованием).

Обновление — 30 ноября 2016 г.

Например:

@using (Ajax.BeginForm("SomeAction", "SomeController", new { someRouteParam = Model.Foo }, new AjaxOptions { UpdateTargetId = "SomeHtmlElementId", HttpMethod = "Post" }))
person rouen    schedule 12.09.2011
comment
Я согласен; тем более, что OP уже создает различное количество частичных представлений с циклом, каждое из которых представляет элемент, за который пользователь должен иметь возможность проголосовать, кажется, что это очень легко добавить к существующему коду. Просто Ajax.BeginForm() вокруг каждой кнопки голосования с идентификатором элемента, окружающего частичное представление, в качестве цели обновления! - person bzlm; 12.09.2011
comment
Спасибо, это избавило меня от головной боли. - person mdlars; 01.12.2016

ASP.NET MVC — идеальный фреймворк для таких нужд. Если бы я был на вашем месте, я бы стал работать с JQuery Ajax API.

Следующий пост в блоге должен дать вам подсказку о том, что вы можете делать с вызовами PartialViews, JQuery и Ajax на сервер:

http://www.tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views

ОБНОВЛЕНИЕ

Его попросили сделать краткое вступление, так что вот оно.

Следующий код является вашим методом действий:

    [HttpPost]
    public ActionResult toogleIsDone(int itemId) {

        //Getting the item according to itemId param
        var model = _entities.ToDoTBs.FirstOrDefault(x => x.ToDoItemID == itemId);
        //toggling the IsDone property
        model.IsDone = !model.IsDone;

        //Making the change on the db and saving
        ObjectStateEntry osmEntry = _entities.ObjectStateManager.GetObjectStateEntry(model);
        osmEntry.ChangeState(EntityState.Modified);
        _entities.SaveChanges();

        var updatedModel = _entities.ToDoTBs;

        //returning the new template as json result
        return Json(new { data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) });
    } 

RenderPartialViewToString — это метод расширения для контроллера. Вам нужно использовать Nuget, чтобы сбросить очень маленький пакет с именем TugberkUg.MVC, который у нас есть расширение контроллера для преобразования частичных представлений в строку внутри контроллера.

Тогда вот краткая информация о том, как вы можете вызвать это с помощью JQuery:

var itemId = element.attr("data-tododb-itemid");
var d = "itemId=" + itemId;
var actionURL = '@Url.Action("toogleIsDone", "ToDo")';

$("#ajax-progress-dialog").dialog("open");

$.ajax({
    type: "POST",
    url: actionURL,
    data: d,
    success: function (r) {
        $("#to-do-db-list-container").html(r.data);
    },
    complete: function () {
        $("#ajax-progress-dialog").dialog("close");
        $(".isDone").bind("click", function (event) {
            toggleIsDone(event, $(this));
        });
    },
    error: function (req, status, error) {
        //do what you need to do here if an error occurs
        $("#ajax-progress-dialog").dialog("close");
    }
});

Нужно предпринять какие-то дополнительные шаги. Итак, посмотрите на сообщение в блоге, в котором есть полное пошаговое руководство.

person tugberk    schedule 12.09.2011
comment
Пожалуйста, включите хотя бы основы в ответ. В противном случае, когда вы измените постоянные ссылки в своем блоге, этот ответ перестанет быть полезным. :) - person bzlm; 12.09.2011
comment
@bzlm Если я свяжу здесь веб-страницу с мышами, я уверен, что ссылка останется там даже через 10 лет. Я обновил свой ответ, хотя. - person tugberk; 12.09.2011
comment
Спасибо! Вы используете флаг isDone в своей базе данных - есть ли шанс сделать это, используя только модель? Т.е. это действительно только для определенного сеанса пользователя..? - person Chris; 12.09.2011
comment
@Chris не уверен, что вы имеете в виду: s Если вы запрашиваете функцию внутри метода действия, это просто пример. Важно то, что мы передаем результат Json для работы внутри кода JavaScript. - person tugberk; 12.09.2011