Вопрос по html, c#, ajax, asp.net, webforms – Как обновить метку статуса внутри запроса ajax

1

У меня есть этот код:


    
        
            
        
    


    
        
            <img src="ajax-loader.gif">
            
        
    

Когда я нажимаю кнопку, анимированный GIF показывает ... это здорово, но процесс занимает больше минуты, и я хотел бы показать пользователю (пока код не сложен), что происходит.

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

lblStatus.Text = "Doing xyz";

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

ОБНОВЛЕНИЕ: ошибка "тип или пространство именlblStatus' не может быть найден".

На изображении вы хотите показать текст метки? Rohit Vyas
Какова точная ошибка? Priyank Patel

Ваш Ответ

4   ответа
5

Вы можете'сделать это с панелями обновления .net, по крайней мере, я неЯ не верю, что это легко. Хотя вы можете сделать это с двумя отдельными вызовами AJAX.

Этот пример использует JQuery для AJAX, а выделенный код находится в vb.net.

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

AJAX

Это ваш главный призыв к длительному процессу. При необходимости вам нужно будет передать данные в метод. Обратите внимание, что есть имя процесса. Это должна быть случайная строка, чтобы вы могли получить статус только этого процесса. У других пользователей будет другое случайное имя процесса, поэтому вы незапутанный статус.

    var processName = function GenerateProcessName() {

        var str = "";
        var alhpabet = "abcdefghijklmnopqrstuvwxyz";
        for (i = 1; i < 20; i++) {
            str += alhpabet.charAt(Math.floor(Math.random() * alhpabet.length + 1));
        }
        return str;
    }


    function StartMainProcess(){
    $j.ajax({
            type: "POST",
            url: "/MyWebservice.asmx/MyMainWorker",
            data: "{'processName' : '" + processName + "','someOtherData':'fooBar'}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                if (msg.d) {                        
                    // do a final timerPoll - process checker will clear everything else
                    TimerPoll();
                }
            }
        });
        TimerPoll();
     }

Ваш второй вызов AJAX будет для другого метода, чтобы получить прогресс. Это будет вызываться каждый XXX раз методом таймера.

Это функция TimerPoll; который будет стрелять каждые 3 секунды в этом случае

function TimerPoll() {
        timer = setTimeout("GetProgress()", 3000)
    }

И, наконец, функция GetProgress () для получения прогресса. Мы должны передать то же имя процесса, что и выше, чтобы процесс вызывался только пользователями.

function GetProgress() {
        // make the ajax call
        $j.ajax({
            type: "POST",
            url: "/MyWebService.asmx/MyMainWorkerProgress",
            data: "{'processName' : '" + processName + "'}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {

                // Evaulate result..
                var process = msg.d

                if (process.processComplete) {
                    // destroy the timer to stop polling for progress
                    clearTimeout(timer);

            // Do your final message to the user here.                      

                } else {

                   // show the messages you have to the user.
                   // these will be in msg.d.messages

                    // poll timer for another trip
                    TimerPoll();
                }
        });

    }

Теперь, в конце, у вас будет пара веб-методов, с которыми взаимодействует ваш AJAX. Вам также понадобится общий / статический объект для хранения всей информации о ходе выполнения, а также всего, что вы хотите передать пользователю.

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

    Public Class ProcessData
        Public Property processComplete As Boolean
        Public Property messages As List(Of String) = New List(Of String)
    End Class

У меня также есть общее свойство, использующее этот класс, которое выглядит следующим образом ... (это общее свойство может содержать несколько процессов, выполняемых несколькими пользователями - отсюда и словарь. Ключом словаря будет имя процесса. Все данные о ходе выполнения будут быть в классе ProcessData

Private Shared processProgress As Dictionary(Of String, ProcessData) = New Dictionary(Of String, ProcessData)

Моя основная рабочая функция выглядит примерно так. Обратите внимание, что сначала мы должны убедиться, что нетт другой процесс, прогресс с тем же

 _
 _
Public Function MyMainWorker(ByVal processName as string, ByVal SomeOtherData as string) as Boolean

        '' Create progress object - GUI outputs process to user
        '' If the same process name already exists - destroy it
        If (FileMaker.processProgress.ContainsKey(processName)) Then
            FileMaker.processProgress.Remove(processName)
        End If

        '' now create a new process
        dim processD as ProcessData = new ProcessData() with {.processComplete = false}


        '' Start doing your long process.

        '' While it's running and after whatever steps you choose you can add messages into the processData which will be output to the user when they call for the updates
         processD.messages.Add("I just started the process")

         processD.messages.Add("I just did step 1 of 20")

         processD.messages.Add("I just did step 2 of 20 etc etc")

         '' Once done, return true so that the AJAX call to this method knows we're done..
        return true

End Function

теперь осталось только вызвать метод progress. Все, что нужно сделать, это вернуть словарь processData, который имеет то же имя processName, которое мы установили ранее.

 _
     _
    Public Function MyMainWorkerProgress(ByVal processName As String) As ProcessData

        Dim serializer As New JavaScriptSerializer()

        If (FileMaker.processProgress.ContainsKey(processName)) Then
            Return processProgress.Item(processName)
        Else
            Return New ProcessData()
        End If

    End Function

И вуаля ..

Итак, подведем итоги.

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

Отказ от ответственности ... У меня нетЯ так долго давал ответ здесь раньше. Он может не соответствовать формату, который люди привыкли видеть. Извините, если все это немного сбивает с толку :) Я скопировал большую часть кода из работающего проекта, поэтому он должен работать ... хотя и нене стреляйте в меня, если есть несколько опечаток :)

Upvote - Спасибо за усилия, я уверен, что это будет полезно для других, но для меня япройду sprocket12
Не беспокойся :)Передача информации о прогрессе пользователю - боль, хотя, как я уже сказал, я нене думаю, что этоили просто, или возможно с панелями обновления .net :) Darren Wainwright
0

Код будет сложным для этого, как вы можете 'сделать это напрямую.

Архитектура запроса ASP.NET AJAX заключается в том, что он нене возвращайте ничего, пока запрос не будет выполнен. Это оставляет вам несколько различных вариантов, включая:

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

2) Запустите операцию в отдельном процессе на обслуживаемом сервере (например, с помощью EXE) и выполните регулярные частичные обратные передачи по таймеру для связи с EXE на сервере, получения текущего состояния и обновления метки

3) Запустите задачу на странице в iframe и используйте Response.Write, чтобы обновить iframe с отключенной буферизацией (или хотя бы сбросить после каждого обновления статуса)

0

Чтобы отобразить статус, вам нужно 2 разных вызова AJAX, один из которых является текущим и основным, который фактически выполняет свою работу, а другой просто для проверки, что текущий статус возвращает действительно простое сообщение.

//Changes the HTML like this

    
        <span id="currentStatu"></span> <img src="ajax-loader.gif">
    


//Javascript
setInterval(jQuery.get(page.aspx?status=1, function () { $("#currentStatu").text(data); } ), 500); // every 0.5 second.

Сложнее было бы узнать, как получить текущий статус со стороны сервера. Если вы можете просто сохранить его в сеансе, это будет самый простой подход, когда запрос ["статус"] == "1" просто верните эту сессию как текст и ничего больше, и все готово.

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

Я надеюсь, что это помогает.

ты ненеобходимо сохранить текущий статус в сеансе. Поскольку сценарии на самом деле работают, статус может быть сохранен в памяти и восстановлен, как мой пример выше. Darren Wainwright
1

Если вы хотите изменить динамически, используйте приведенный ниже код,

Создайте функцию как ниже

function ChangeUpdateProgress(message)
{  
  document.getElementById('lblStatus').innerText=message;
}

Вызвать функциюOnClick событий




Надеюсь это поможет..

Речь идет не о добавлении текста в первый раз, а об обновлении его из кода, находящегося в процессе выполнения действия. sprocket12
Отредактировал мой пост с вашим требованием .. попробуйте это Prasad Kanaparthi

Похожие вопросы