04 апреля 2015
Кравченко Виктор

Как сделать индикатор прогресса (ProgressBar) обновляющийся с сервера (ASP.NET, AJAX, JQuery) — часть 2

VB.NET JQuery JavaScript HTML ASP.NET Web
02

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

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми.
03 На заметку:
О том как отправлять данные в формате JSON можно прочитать в статье Как сделать так, чтобы контроллер вернул данные в формате JSON.
04

Теперь определимся со структурой JSON-объекта для нашего прогресс-бара. Добавим в наш проект Codius.SimpleProgressBar_v1.0.rar (47,0 KB) из первой части класс ProgressData:

05 VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Json <DataContract()>
Public Class ProgressData <DataMember(Name:="description", IsRequired:=True)> Public description As String ' Здесь будем передавать текстовую сопровождающую информацию <DataMember(Name:="percentage", IsRequired:=True)> Public percentage As Decimal ' Здесь будем передавать процентное состояние операции
Public Sub New() Me.New("", 0) End Sub
Public Sub New(description As String, percentage As Decimal) Me.percentage = percentage Me.description = description End Sub
End Class
ProgressData.vb
06 На заметку:
Если проект создается с нуля, возможно понадобится добавить в проект референс на пространство имен System.Runtime.Serialization.
07

В классе ProgressManager и в интерфейсе IProgressManager удаляем процедуры:

08
  • Public Sub SetCompleted(ByVal taskId As String, ByVal percentage As Int32)
  • Public Sub SetCompleted(ByVal taskId As String, ByVal [step] As String)
09

Изменяем интерфейс IProgressManager:

10 VB.NET
1
2
3
4
5
6
Namespace Framework.Abstractions
Public Interface IProgressManager Sub <b>SetCompleted</b>(ByVal taskId As String, ByVal progress As ProgressData) Function GetStatus(ByVal taskId As String) As String End Interface
End Namespace
IProgressManager.vb
11

И добавляем небольшой фрагмент кода в объект ProgressManager (измененная реализация метода SetCompleted). Поскольку JSON это текстовый формат обмена данными, то и тип данных, передаваемый в кэш, будет String:

12 VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Imports Codius.Framework.Abstractions Imports System.Runtime.Serialization.Json Imports System.IO
Namespace Framework
Public Class ProgressManager Implements IProgressManager ' ... ' Вместо удаленных двух методов - оставляем один модифицированный
Public Sub SetCompleted(ByVal taskId As String, ByVal progress As ProgressData) Implements Abstractions.IProgressManager.SetCompleted If String.IsNullOrEmpty(taskId) Then Exit Sub End If Dim JSON As String = "" ' Преобразуем объект progress в JSON JSON = СериализоватьJSONвСтроку(progress, New DataContractJsonSerializer(GetType(ProgressData))) _dataProvider.Set(taskId, JSON) End Sub
Private Function СериализоватьJSONвСтроку(obj As Object, js As DataContractJsonSerializer) As String Dim stream As MemoryStream = New MemoryStream js.WriteObject(stream, obj) stream.Position = 0 Dim sr As StreamReader = New StreamReader(stream) Dim jsonString = sr.ReadToEnd() Return jsonString End Function
' ... End Class
End Namespace
ProgressManager.vb
13

В общем-то и все, остается на сервере адаптировать процедуру информирования:

14 VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Imports Codius.Framework Imports System.Threading
Public Class HomeController Inherits SimpleProgressController
Function Index() As ActionResult Return View() End Function
Public Function DoWorkProgress() As String Dim taskId = GetTaskId() For i As Integer = 0 To 100 Dim state As String = "" If i < 15 Then state = "Получение основных записей..." ElseIf i < 25 Then state = "Подготовка данных к обработке..." ElseIf i < 50 Then state = "Обработка данных..." ElseIf i < 80 Then state = "Сохранение полученных результатов..." ElseIf i < 95 Then state = "Удаление временных данных..." End If ProgressManager.SetCompleted(taskId, New ProgressData(state, CDec(i))) Thread.Sleep(Rnd(1) * 300) Next Return String.Format("{0} Завершено!", taskId) End Function
End Class
HomeController.vb
15

... и на клиенте распарсить получаемые данные и преподнести пользователю:

16 HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@Code Layout = Nothing End Code <!DOCTYPE html>
<html>
<head> <meta name="viewport" content="width=device-width" /> <title>Codius.ru - SimpleProgressBar Sample</title> <script src="~/Script/SimpleProgress-Fx.js"></script> <script src="~/Script/jquery-1.10.2.min.js"></script> @*Не забываем про JQuery*@ </head>
<body>
<style type="text/css"> #prBarLine { position: relative; display: inline-block; padding:1px; border: 1px solid rgb(200,200,200); height: 6px; margin-top:.4em; width:300px; } #prBarLineBlock { position: relative; height: 100%; background-color: rgba(0, 85, 204, 0.8); } </style>
<script type="text/javascript"> $(document).ready(function () { $("#buttonStart").bind("click", buttonStartHandler); }); function buttonStartHandler() { $("#prBarText").text(""); new SimpleProgress() .setInterval(300) .callback(function (json) { var JSONdata = JSON.parse(json); var w = JSONdata.percentage; var status = JSONdata.description; $('#prBarLineBlock').animate({ 'width': w +'%'}, 100); $("#prBarText").text(status); // без анимации: //$("#prBarLineBlock").width(w); // или так: // $("#prBarLineBlock").css('width', w); }, function (response) { $("#prBarText").text("Завершено!"); $('#prBarLineBlock').animate({ 'width': '100%' }, 100); }) .start("/home/doworkprogress", "/home/progress"); } </script>
<div style="text-align:center; padding-top:2em;"> Пример расширенного прогресс-бара от Codius.ru - одновременное <br/>получение всей информации о состоянии операции.<br /><br /><br /> <input id="buttonStart" type="button" value="Старт" /> <div id="prBarText"></div> <div id="prBarLine"> <div id="prBarLineBlock" style="width:0%"> </div> </div> </div> </body>
</html>
Index.vbhtml
17
Вы можете дополнить объект ProgressData по своему усмотрению.
18 На заметку:
Файл проекта можно скачать по ссылке Codius.ExtProgressBar_v1.0.rar (46,8 KB). Проект создан в Visual Studio 2013 Ultimate.
20

Похожие запросы:

  • Client Server Progress Bar
  • Reporting Progress from Tasks
  • jQuery Progress Bar in ASP.Net
  • Progress bar for long running server calls in ASP.Net MVC
comments powered by HyperComments