Прототип Ajax.PeriodicalUpdater вставляет пустую строку, когда сервер недоступен - PullRequest
2 голосов
/ 13 января 2009

Я использую следующее, чтобы получить обновленный HTML и вставить его в div с идентификатором "content"

var updater = new Ajax.PeriodicalUpdater('content', '/Doc?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
  });

Проблема в том, что когда сервер выключен (он работает внутри приложения, которое модифицирует данные и выполняет серверную обработку данных), программа обновления просто очищает содержимое div.

Есть ли способ сделать так, чтобы, когда PeriodicalUpdater истекает, получал 404 и т. Д., Он просто оставлял содержимое без изменений? Я бы предпочел, чтобы последние доступные данные просто оставались там, а не стирались.


Для полноты, это весь мой код:

<html>
<head>
<title></title>
<script type="text/javascript" src="/Prototype"></script>
<script type="text/javascript">
var css;
var css_data;

function load_content()
{
  var d = new Date();

  css = document.createElement('style');
  css.setAttribute('type', 'text/css');
  if(css.styleSheet) { css.styleSheet.cssText = '';} //Because IE is evil
  else { css_data = document.createTextNode(''); css.appendChild(css_data); } //And everyone else is cool
  document.getElementsByTagName("head")[0].appendChild(css);

  var updater = new Ajax.PeriodicalUpdater({success: 'content'}, '/%doc_path%?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
    onSuccess: function(transport) {
          new Ajax.Request('/%css_path%?'+d.getTime(), {
              method: 'post',
              onSuccess: function(transport) {
                if(css.styleSheet) { css.styleSheet.cssText = transport.responseText}
                else { 
                    var new_css_data = document.createTextNode(transport.responseText);
                    css.replaceChild(new_css_data, css_data); 
                    css_data = new_css_data;
                } 
              }
          });
          new Ajax.Request('/%title_path%?'+d.getTime(), {
              method: 'post',
              onSuccess: function(transport) {
                document.title = transport.responseText;
              }
          });
    }
  });
}

</script>

</head>

<body>
<div id="content"></div>

<script type="text/javascript">
    load_content();
</script>

</body>
</html>

Как видите, я попробовал решение Триптиха ... но все равно не пошел. Он обновляется с пустыми данными, когда запрос все еще не удается. Поскольку сейчас у меня есть все это, может ли кто-нибудь увидеть какие-либо ошибки, которые я совершаю.

Примечание: игнорируйте строки, такие как% doc_path% ... это просто управляющие строки, которые я использую, чтобы впоследствии их можно было программно заменить на правильный путь для каждого документа ... все, что сделано на сервере и на самом деле не выполняется не имеет значения для этого.


@ Vinze

Согласно документации, onFailure «вызывается, когда запрос завершается и его код состояния существует, но отсутствует в семействе 2xy. Это пропускается, если определен обратный вызов для конкретного кода, и происходит до onComplete».

Но если сервер был остановлен, не истечет ли время ожидания и не будет ли вообще никакого кода состояния? Может я неправильно это понимаю ...

Ответы [ 4 ]

1 голос
/ 13 января 2009

Передайте объект (не строку) в качестве первого параметра в PeriodicalUpdater. Значение с ключом «success» будет вызываться только при успешных вызовах AJAX.

new Ajax.PeriodicalUpdater({success: 'content'}, '/Doc?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
  });

Подробнее об Ajax.Updater (от которого наследуется PeriodicalUpdater)

1 голос
/ 13 января 2009

вы можете добавить опцию onFailure в список опций, так как Ajax.PeriodicalUpdater наследует свойства Ajax.Request (http://www.prototypejs.org/api/ajax/request)

С другой стороны, вас может заинтересовать использование "onComplete" или любого из "жизненного цикла запроса" по ссылке ниже

0 голосов
/ 14 января 2011

Подробнее об этом.

Ajax.PeriodicalUpdater не наследуется от Ajax.Updater, как описано в http://www.prototypejs.org/api/ajax/periodicalupdater:

Ajax.PeriodicalUpdater не является специализацией Ajax.Updater, несмотря на его название.

Он передает необязательные параметры Ajax.Updater (сам по себе класс, который наследует от Ajax.Request), что, по-видимому, подразумевает, что он эквивалентен созданию экземпляра Ajax.Request и передаче ему обратных вызовов.

Я протестировал и могу подтвердить, что добавление функции onFailure не работает в этом случае. Также не добавляется onException.

Можно ожидать, что оба будут работать, поскольку они передаются в объект Ajax.Updater, созданный Ajax.PeriodicalUpdater. Однако после некоторой отладки кажется, что Ajax.Updater никогда не рассматривает недоступный сервер как исключение или сбой. Таким образом, контейнер для успеха всегда обновляется (в данном случае он очищается), даже если он определен как {success: 'content', fail: 'failContent'}.

Кроме того, согласно моим тестам, Ajax.Updater (и Ajax.PeriodicalUpdater) не вызывает ни onSuccess (), ни onComplete (), когда сервер не отвечает.

Фактически, единственный обратный вызов, который мне удалось получить, это on0, как показано ниже:

new Ajax.PeriodicalUpdater('content', 'url', {
    frequency: 5,
    on0: function(requester, exception) {
        alert("ERROR 0");
    }
});

Похоже, что 0 - это код ошибки Ajax.Request (родительский класс для Ajax.Updater), когда сервер недоступен.

Плохая новость заключается в том, что on0 () вызывается до , когда содержимое обновляется / очищается, что означает, что невозможно заменить это содержимое на пользовательское.

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

Это верно как для Ajax.PeriodicalUpdater, так и для Ajax.Updater. Это означает, что единственный способ получить требуемое поведение - использовать Ajax.Request напрямую.

0 голосов
/ 13 января 2009

Как насчет того, чтобы сделать все это самостоятельно?

Начните с функции, которая будет вызывать обновление:

function requestMoreInfo(){
new Ajax.Request('url',
  {
    method:'get',
    parameters:  "someget=here",
    onSuccess: handleTheReturn
  });

}

Затем создайте функцию, которая будет обрабатывать ответ от сервера:

function handleTheReturn(reply){
    var newMessages = eval('(' + reply.responseText + ')');
    //update your element or whatever
} 

А затем запускайте его каждые 20 (или что угодно) секунд с помощью:

new PeriodicalExecuter(requestMoreInfo, 20);

Затем просто добавьте первый requestMoreInfo к вашей функции загрузки и готово к работе ... сейчас, чтобы решить вашу проблему, просто проверьте переменную newMessages в функции handleTheReturn, и вы сможете делать все что угодно (заставить сервер отправлять JSON объект, который нужно знать, в порядке, или, возможно, некоторые другие коды, или найдите конкретные ошибки, которых вы хотите избежать!

...