none
Ajax AutoUpdate по таймеру RRS feed

  • Вопрос

  • Добрый день, прошу подсказать в решение следующей задачи.
    В контроллере Admin Имеем метод который возвращает строку

    public string Process(){...}

    Необходимо после нажатия на кнопку обращаться к методу и выводить результат в DIV пока метод не вернет 0.

    Пробую так:

    <div id="MessageProgress">Обработанно файлов: 0

    </div><input type="submit"  value="Обработать" class="btGreen" onc lick="StartLoad();"/>


    кнопка запускает JScript,

    function StartLoad() 

       {$.ajax("/Admin/Process", { success: SendRequest_Success, error: SendRequest_Error });            } 

    function SendRequest_Success(result)

    {  while (result != "0") {

                  $('#MessageProgress').text('Обработанно файлов: ' + result);

                setTimeout(StartLoad(), 1000);        }   

    }


    Как догадались, это не работает, просьба подсказать в чем проблема.
    Спасибо.


    • Изменено shidlat 31 мая 2012 г. 10:48 более читабельный код

Ответы

  • Фу, только домой доехал, иначе быстрее бы выложил. Вот собственно то, что Вы хотите.

    @*TestView*@
    @model IEnumerable<string>
    <!DOCTYPE html>
    <html>
    <head>
      <title>TestView</title>
      <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    </head>
    <body>
      <div id="MessageProgress">
        Обработанно файлов: 0
      </div>
      <button id="StartButton">
        Запустить</button>
      <script type="text/javascript">
        var interval, processed = false;
        $(document).ready(function () {
          $("#StartButton").click(function () {
            if (processed);
            else {
              processed = true;
              interval = window.setInterval("ProgressStatus()", 50);
            }
          });
        });
    
        function ProgressStatus() {
          $.post('@Url.Action("ProgressStatus")', null, function (data) {
            if (data.Succes) {
              if (data.Count > 0)
                $('#MessageProgress').text('Обработанно файлов: ' + data.Count);
              else {
                window.clearInterval(interval);
                processed = false;
                $('#MessageProgress').text("Завершено");
              }
            }
          }, "json");
        }
      </script>
    </body>
    </html>
    

    namespace MvcApplication.Controllers
    {
      public class TestController : Controller
      {
        public TestController()
        {
        }
        public ActionResult Index()
        {
          if (HttpContext.Application["FilesCount"] == null)
            HttpContext.Application["FilesCount"] = 100;
          return View("~/Views/Test/TestView.cshtml");
        }
        [HttpPost]
        public JsonResult ProgressStatus(string NewValue)
        {
          JsonResult result = new JsonResult();
          try
          {
            uint count = GetFilesCount();// Получаем количество оставшихся файлов
            result.Data = new { Succes = "true", Count = count };
          }
          catch (Exception e)
          {
            result.Data = new { Succes = "false", Count = -1 };
          }
          return result;
        }
        //Реализация данного метода у Вас своя, берёт данные из отдельного потока или ещё откуда то.
        //В моё случае это метод-заглушка.
        private uint GetFilesCount()
        {
          HttpContext.Application["FilesCount"] = Convert.ToUInt32(HttpContext.Application["FilesCount"]) - 1;
          return Convert.ToUInt32(HttpContext.Application["FilesCount"]);
        }
    
      }
    }

    • Помечено в качестве ответа shidlat 1 июня 2012 г. 5:45
    Модератор
  • Большое спасибо, то, что нужно.

    На сколько я понимаю это примерно такое же решение как у Дино Эспозито

    ссылка

    Или его подход более предпочтительнее?

Все ответы

  • Что за ресурс вы передаёте на клиент, можно более понятно, что конкретно надо реализовать? И циклический запрос к веб-серверу не лучшая идея.
    Модератор
  • По поводу задачи, все просто:

    Есть кнопка она же

    <input type="submit"  value="Обработать" class="btGreen" onc lick="StartLoad();"/>

    при нажатие на неё на сервере запускается весьма длительный процесс обработки файлов. Этот

    Все, что я хочу, это дать пользователю наблюдать за процессом, при этом крайне желательно отображать реальный процесс, а не просто надпись в стили "Загрузка, подождите"

    для этого я создал метод, он же

    public string Process(){...}

    При первом обращение он запускает в потоке метод обработки файла, передавая в качестве значения ссылку на объект в котором находится информация о количестве обработанных файлов.

    В вкратце как то так.



  • Фу, только домой доехал, иначе быстрее бы выложил. Вот собственно то, что Вы хотите.

    @*TestView*@
    @model IEnumerable<string>
    <!DOCTYPE html>
    <html>
    <head>
      <title>TestView</title>
      <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    </head>
    <body>
      <div id="MessageProgress">
        Обработанно файлов: 0
      </div>
      <button id="StartButton">
        Запустить</button>
      <script type="text/javascript">
        var interval, processed = false;
        $(document).ready(function () {
          $("#StartButton").click(function () {
            if (processed);
            else {
              processed = true;
              interval = window.setInterval("ProgressStatus()", 50);
            }
          });
        });
    
        function ProgressStatus() {
          $.post('@Url.Action("ProgressStatus")', null, function (data) {
            if (data.Succes) {
              if (data.Count > 0)
                $('#MessageProgress').text('Обработанно файлов: ' + data.Count);
              else {
                window.clearInterval(interval);
                processed = false;
                $('#MessageProgress').text("Завершено");
              }
            }
          }, "json");
        }
      </script>
    </body>
    </html>
    

    namespace MvcApplication.Controllers
    {
      public class TestController : Controller
      {
        public TestController()
        {
        }
        public ActionResult Index()
        {
          if (HttpContext.Application["FilesCount"] == null)
            HttpContext.Application["FilesCount"] = 100;
          return View("~/Views/Test/TestView.cshtml");
        }
        [HttpPost]
        public JsonResult ProgressStatus(string NewValue)
        {
          JsonResult result = new JsonResult();
          try
          {
            uint count = GetFilesCount();// Получаем количество оставшихся файлов
            result.Data = new { Succes = "true", Count = count };
          }
          catch (Exception e)
          {
            result.Data = new { Succes = "false", Count = -1 };
          }
          return result;
        }
        //Реализация данного метода у Вас своя, берёт данные из отдельного потока или ещё откуда то.
        //В моё случае это метод-заглушка.
        private uint GetFilesCount()
        {
          HttpContext.Application["FilesCount"] = Convert.ToUInt32(HttpContext.Application["FilesCount"]) - 1;
          return Convert.ToUInt32(HttpContext.Application["FilesCount"]);
        }
    
      }
    }

    • Помечено в качестве ответа shidlat 1 июня 2012 г. 5:45
    Модератор
  • Большое спасибо, то, что нужно.

    На сколько я понимаю это примерно такое же решение как у Дино Эспозито

    ссылка

    Или его подход более предпочтительнее?

  • Да, общая идея та же, просто мой вариант написан на скорую руку, а у него более продуманное и полное решение, он же профессионал в конце-концов.
    2 июня 2012 г. 13:45
    Модератор