Не обновлялись данные после публикации (mvc razor)

Я использую "Composite C1" cms, mvc и движок razor view. На некоторых страницах должны отображаться элементы списка, и пользователь может фильтровать данные по некоторым критериям. Первая часть работает нормально (элементы отображаются без проблем), у меня проблема со второй частью - отфильтрованные данные не обновляются, на странице отображаются старые данные.

У меня ItemsController:

public class ItemsController : Controller
{
    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult Filter()
    {
        // Initialize all filter comboboxes for Items page
        // ...
        return View(new MyModel());
    }

    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult List()
    {
        // Set first default items
        ViewBag.Items = (IEnumerable)GetRandomItems(8);

        return View(new MyModel());
    }

    [HttpPost]
    [ValidateInput(true)]
    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult List(MyModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // Set filtered items
        // ...
        ViewBag.Items = (IEnumerable)itemList;

        return Json(new { Success = true, Filter = filter, ItemNumber = itemList.Count }, JsonRequestBehavior.AllowGet);
    }
}

И у меня есть два представления: «List.cshtml» - для отображения данных и «Filter.cshtml» - для создания критериев для фильтрации данных.

В представлении «Фильтр» есть сценарий, который запрашивает / Items / List, - для фильтрации и обновления данных.

<script type="text/javascript" language="javascript">
/* <![CDATA[ */
    $(document).ready(function () {
        $("#search_button_filter").bind('click', function() {
            var $form = $("#filter_form");
            $.ajax({
                url: '/Items/List/default.aspx',
                type: 'POST',
                data: $form.serialize(),
                success: function (data) {
                    if (data.Success) {
                        // Show report: amount of filtered items, etc.
                        // ...
                    }
                }
            });
            return false;
        });
    });
/* ]]> */
</script>

Я проверил - "ActionResult List (MyModel model)" установил правильные отфильтрованные данные в следующей строке кода.

ViewBag.Items = (IEnumerable)itemList;

Но в представлении «Список» по-прежнему отображаются предыдущие данные.

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

Спасибо.

Новое обновление

Я переделал свое решение, и теперь оно работает. Те же два представления «Список» и «Фильтр» на моей странице, но без каких-либо Rest / Post, только Get и QueryString:

<script type="text/javascript" language="javascript">
/* <![CDATA[ */
    $(document).ready(function () {
        $("#search_button_filter").bind("click", function() {
            var $filter1 = $("#filter1_search_filter").val();
            var $filter2 = $("#filter2_search_filter").val();
            var $filter3 = $("#filter3_search_filter").val();
            window.location.href = "@UrlUtil.ItemsPageUrl" + "?&filter1=" + $filter1 + "&filter2=" + $filter2 + "&filter3=" + $filter3;
        });
    });
/* ]]> */
</script>

Но сейчас у меня очень маленькая проблема. Количество элементов рассчитывается в методе «ActionResult List ()» (который инициализирует представление «Список»), но мне нужно отобразить это значение в представлении «Фильтр». Пробовал использовать коллекцию TempData - установил

[OutputCache(CacheProfile = "ZeroCacheProfile")]
public ActionResult List()
{
    TempData["AmountOfFilteredItems"] = null;

    Guid filter1;
    if (!Guid.TryParse(Request.QueryString["filter1"], out filter1))
    {
        filter1 = Guid.Empty;
    }

    Guid filter2;
    if (!Guid.TryParse(Request.QueryString["filter2"], out filter2))
    {
        filter2 = Guid.Empty;
    }

    Guid filter3;
    if (!Guid.TryParse(Request.QueryString["filter3"], out filter3))
    {
        filter3 = Guid.Empty;
    }

    List<MyModel> items;
    if ((filter1 == Guid.Empty) && (filter2 == Guid.Empty) && (filter3 == Guid.Empty))
    {
        items = GetRandomItems(8);
    }
    else
    {
        items = GetFilteredItems(filter1, filter2, filter3);
    }

    TempData["AmountOfFilteredItems"] = items.Count;

    return View(items);
}

значение в методе ActionResult List () контроллера Items и вернуть это значение в представлении Filter:

@model MyModel
@using (Html.BeginForm("Items", "Filter", FormMethod.Post, new { @id = "filter_form" }))
{
    <!-- Fill required data -->
    <!-- ... -->
    <font class="bold">@(TempData["AmountOfFilteredItems"].NotNull() ? TempData["AmountOfFilteredItems"] : 0)</font>
}

Только одна проблема: это значение всегда задерживается на один шаг / итерацию - если реальное количество элементов равно «2», тогда в представлении отображается предыдущее значение «8». И в следующий раз, когда действительное число будет «0», отобразится предыдущее действительное значение «2».

Как я могу это решить?


person Maxim Polishchuk    schedule 30.04.2011    source источник
comment
Что вы имеете в виду, говоря, что в представлении списка продолжают отображаться предыдущие данные? Вы имеете в виду после запроса ajax или если вы вернетесь в / Items / List?   -  person Danny Tuppeny    schedule 01.05.2011
comment
Вы не включили код внутри if (data.Success), который выглядит важной частью, поскольку именно туда возвращаются данные?   -  person Danny Tuppeny    schedule 01.05.2011
comment
Привет, я подумал, что когда я устанавливал новые (отфильтрованные) элементы в хранилище ViewBag.Items (в методе «ActionResult List (MyModel model)» во время «публикации»), то представление «Список» (которое использует это хранилище для инициализации) будет обновляться автоматически - представление «Список» будет связывать новые данные и отображать их ... Я не хотел бы связывать его внутри клиентской части if (data.Success) вручную, было бы лучше найти способ сделать это на сервере боковая сторона.   -  person Maxim Polishchuk    schedule 02.05.2011
comment
Я забыл добавить, что эти два представления «Фильтр» и «Список» находятся на одной странице.   -  person Maxim Polishchuk    schedule 02.05.2011
comment
Можете ли вы опубликовать полный код действия, включающего получение данных и установку переменной TempData?   -  person Danny Tuppeny    schedule 02.05.2011
comment
См. Мой ответ re: TempData vs ViewData, посмотрите, решит ли это проблему   -  person Danny Tuppeny    schedule 02.05.2011


Ответы (2)


HTML-код в браузере не будет обновляться, пока вы его не обновите. Код в браузере не связан с тем, что происходит на сервере. Если вы используете Ajax для отправки запроса на сервер, вам необходимо обработать ответ и что-то с ним сделать.

Если вы хотите использовать Ajax, вам необходимо убедиться, что ваш метод List (MyModel) возвращает частичное представление, а затем перезаписывает им раздел вашей DOM.

Однако проще всего удалить Ajax и обработать его как обычную обратную передачу страницы - это будет намного проще. Это немного устарело, но здесь есть некоторая информация о сообщениях формы в MVC:

http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx

person Danny Tuppeny    schedule 02.05.2011
comment
спасибо, вчера так же подумал и немного переделал свое решение - работает, но у меня очень маленькая проблема. Я не знаю, можно ли создать новый вопрос, если предметы / контекст связаны, поэтому я обновил свой текущий вопрос. - person Maxim Polishchuk; 02.05.2011

Я только что прочитал, что цель TempData - предоставить данные для «следующего» запроса, поэтому мне интересно, видит ли «текущий» запрос только TempData из «предыдущего» запроса, следовательно, он не соответствует требованиям.

Попробуйте вместо этого перейти на ViewBag и посмотрите, решит ли это проблему.

Например. в моем действии я добавил:

ViewBag.ItemCount = 10;

(Примечание: это динамический объект, поэтому вы можете создавать свойства по ходу).

Затем, чтобы отобразить это, я добавил это в свое представление:

Count: @ViewBag.ItemCount

Кажется, работает, как ожидалось.

person Danny Tuppeny    schedule 02.05.2011
comment
ViewData всегда возвращает «ноль». И я думаю, что это нормально, потому что «get» и «set» ViewData в этом случае имеют разную область видимости - «set» находится в действии «List», «get» - в представлении «Filter». - person Maxim Polishchuk; 02.05.2011
comment
Хм, я думаю, это должно сработать, но на самом деле я имел в виду ViewBag. Я обновил свой ответ - я только что это проверил, и, похоже, все работает нормально :-) - person Danny Tuppeny; 02.05.2011
comment
Mate, ViewBug и ViewData одинаковы (очень похожи). Но это не важно. Вы пробовали использовать 2 разных представления (с двумя разными действиями в контроллере) на одной странице или только 1 представление на одной странице ??? - person Maxim Polishchuk; 02.05.2011
comment
Извините, я не знал, что вы использовали его дважды. Не могли бы вы также установить значение в ViewBag в действии «Фильтр» или также установить его в TempData для использования в представлении «Фильтр»? - person Danny Tuppeny; 02.05.2011