Непрерывное обновление PartialView с использованием ASP.NET MVC 3

Я разрабатываю веб-сайт с использованием ASP.NET MVC 3.

У меня есть ряд разделов, содержащих новости из разных отделов, как показано на рисунке ниже:

http://i.stack.imgur.com/G21qi.png

Разделы добавляются на главную страницу с помощью

@Html.Action("_News", "Home", new { id = 1 })

Где id 1 = "Ledelsen", 2 = "Omstillingen" и так далее.

Мой контроллер содержит следующее действие:

[ChildActionOnly]
public ActionResult _News(int id)
{
    // controller logic to fetch correct data from database
    return PartialView();
}

Я установил и запустил CRUD, но мой вопрос в том, как я могу обновить PartialViews без обратной передачи с заданным интервалом?

Я предполагаю, что для этого мне нужно использовать Javascript/jQuery, но я не смог.

Может ли кто-нибудь указать мне правильное направление или, что еще лучше, привести пример того, как это сделать?

заранее спасибо

РЕДАКТИРОВАТЬ: Просто чтобы уточнить, я не хочу, чтобы вся страница обновлялась, а только асинхронное обновление частичных представлений.


person Casper    schedule 29.05.2011    source источник


Ответы (2)


В вашем частичном представлении я бы предложил обернуть все это в div:

<div id="partial1">

В javascript вам понадобится функция для использования AJAX для загрузки частичного представления в div:

$("#partial1").load("_News", { id="1"} );

Это использование jQuery. Некоторая документация здесь. По сути, это заменит указанный div представлением, созданным в результате вызова вашего действия _News. Идентификатор можно изменить, если вы добавите некоторую логику к вызову javascript.

Затем оберните вызов load() в setTimeout():

var t = setTimeout(function () {$("#partial1").load("_News", { id="1"} );}, 60000);

Это будет запускать включенную функцию каждые 60 секунд. t можно использовать, таким образом, clearTimeout(t) в любом месте вашего кода javascript, чтобы остановить автоматическое обновление.

ИЗМЕНИТЬ

Это должно решить проблему кэширования. Спасибо @iko за предложение. Я заметил, что вам нужно cache: false, чтобы это работало.

var t = setTimeout(function () { $.ajax({ 
                                     url: "_News", 
                                     data: { "id": "1" }, 
                                     type: "POST", 
                                     cache: false, 
                                     success: function (data) { 
                                          $("#partial1").innerHTML = data; 
                                     }}); }, 60000);
person Steve Mallory    schedule 29.05.2011
comment
Я, типа, не эксперт по jQuery, но вам не хватает функции-оболочки для вызова в setTimeout? Это выглядит так, как будто он вызывает загрузку, а затем передает все, что возвращает функция загрузки (объект запроса?) в setTimeout, что, как я полагаю, приведет к ошибке. - person AHM; 30.05.2011
comment
@AHM Я думаю, что пример правильный, хотя я бы не сказал, что он полный. .load() — это оболочка вокруг .ajax(). Он загружает возвращенный html в вызывающий элемент. Вы можете включить функцию обратного вызова, но это не обязательно. А setTimeout просто вызывает код включения по расписанию. - person Steve Mallory; 30.05.2011
comment
Хммм.... если load не возвращает замыкание, то это неправильно. SetTimeout определенно требует обратного вызова в качестве первого аргумента. Я думаю, что это должно быть setTimeout(function(){$(#partial1).load(_News, {id=1})}, 60000) - person AHM; 30.05.2011
comment
@AHM Да, ты прав. Я исходил из памяти, всегда плохое решение в моем случае. Я обновляю свой ответ. Спасибо. - person Steve Mallory; 30.05.2011
comment
В итоге я использовал это решение, которое отлично работало на локальном хосте. Однако на сервере он всегда обновляет разделы в соответствии с их содержимым при загрузке страницы. Это означает, что даже если я что-то отправлю, он будет ждать 60 секунд, и при первой перезагрузке jQuery загрузит старый контент, как будто он его кэширует. Любые идеи? Как я уже сказал, он отлично работает на моей локальной машине. - person Casper; 07.06.2011
comment
В качестве примечания: если я вручную загружу раздел в новую вкладку, используя /Home/_News/1 (или 2/3), я получу фактический контент, и как только он будет загружен, другая вкладка будет правильно загружена при следующем обновить, но только для этого обновления. Проблема сохраняется, когда отправляется больше данных (или удаляется, если на то пошло). - person Casper; 07.06.2011
comment
@Casper Вам нужно использовать $.ajax( type: "POST", ... ) или $.post(...), чтобы предотвратить, например. IE от кеширования. IE будет агрессивно кэшировать и показывать одни и те же данные, даже если вы отправите другой идентификатор с аналогично сформированным запросом через Ajax. По этой причине я бы рекомендовал изменить пример на $.post или $.ajax. - person lko; 01.03.2012

Я собираюсь направить вам ответ, который я дал на связанный вопрос UpdatePanel в Razor (mvc 3) для отправной точки . Обратите внимание, что он не сильно отличается от ответа Стива Мэллори, но подчеркивает некоторые другие моменты.

Разница, однако, в том, что вам может потребоваться удалить атрибут [ChildActionOnly], если вы хотите обновить каждое частичное представление по отдельности (обновить только идентификатор 1 или обновить только идентификатор 2).

Этот скрипт можно поместить в возвращаемый партиал.

<script type="text/javascript">
    setInterval(function()
    {
          $.load('<%= Url.Action("_News", "Home", new { id = Model.Id } ) %>', function(data) {
          $('#partial_'@(Model.Id)').html(data);
      });
    }
    , 30000);
</script>

<div id="partial_@(Model.Id)" />
person Ahmad    schedule 30.05.2011