01 |
Предположим, что в проекте существует некая функция/процедура, исполнение которой может быть затянуто на время, не сопоставимое со среднестатистическим временем загрузки страницы — 10 сек и более. К примеру, существует метод в контроллере, который собирает информацию с нескольких интернет страниц и выводит сводные результаты: |
Статья написана на основе материалов статьи Дино Эспозито "Контекстно-зависимый индикатор прогресса для ASP.NET MVC" в Журнале MSDN Magazine за декабрь 2011.
|
02 | VB.NET |
1 2 3 4 5 6 7 8 9 Public Function SomeMethod() As ActionResult ... |
|
03 |
О функции ПолучитьСодержимоеСтраницы() можно почитать в статье Как получить содержимое произвольной вебстраницы. |
|
04 |
|
SimpleProgressBar в действии — информация о статусе получена с сервера.
|
05 |
Суть идеи прогресс-бара проста и заключается в следующем: |
|
06 |
|
|
08 |
На примере встраивания в готовый проект покажу, как это работает. Серверная сторона состоит из 5 файлов: |
|
09 |
|
|
10 | VB.NET |
1 2 3 4 Public Interface IProgressDataProvider ... |
IProgressDataProvider.vb
|
11 | VB.NET |
1 2 3 4 5 Public Interface IProgressManager ... |
IProgressManager.vb
|
12 |
|
|
13 | VB.NET |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Public Class AspnetProgressProvider ... |
AspnetProgressProvider.vb
|
14 |
|
|
15 | 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 37 38 39 40 41 42 43 44 45 46 47 48 Imports Codius.Framework.Abstractions
Namespace Framework ... |
ProgressManager.vb
|
16 |
|
|
17 | VB.NET |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Namespace Framework ... |
SimpleProgressController.vb
|
18 |
Клиентская сторона состоит из единственного скрипта SimpleProgress-Fx.js — объект-функция SimpleProgress, которая берет на себя весь клиентский функционал: |
|
19 | JavaScript |
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 75 76 77 78 79 80 81 82 83 84 85 86 87 var SimpleProgress = function () {
var that = {};
// Get the current task ID
that._taskId = 0;
// Get the timer ID used to push refreshes
that._timerId = 0;
// Get the URL to invoke to read status
that._progressUrl = "";
// Get the current interval for progress refresh
that._interval = 500;
// Get the user-defined callback that refreshes the UI
that._userDefinedProgressCallback = null;
// Get the user-defined callback that finalizes the call
that._taskCompletedCallback = null;
// Get a new task ID
that.createTaskId = function () {
var _minNumber = 100,
_maxNumber = 1000000000;
return _minNumber + Math.floor(Math.random() * _maxNumber);
};
// Set progress callback
that.callback = function (userCallback, completedCallback) {
that._userDefinedProgressCallback = userCallback;
that._taskCompletedCallback = completedCallback;
return this;
};
// Set frequency of refresh
that.setInterval = function (interval) {
that._interval = interval;
return this;
};
// INTERNAL FUNCTION
that._internalProgressCallback = function () {
that._timerId = window.setTimeout(that._internalProgressCallback, that._interval);
$.ajax({
url: that._progressUrl,
cache: false,
headers: { 'X-SimpleProgress-TaskId': that._taskId },
success: function (status) {
if (that._userDefinedProgressCallback != null)
that._userDefinedProgressCallback(status);
}
});
};
// Invoke the URL and monitor its progress
that.start = function (url, progressUrl) {
that._taskId = that.createTaskId();
that._progressUrl = progressUrl;
// Place the Ajax call
$.ajax({
url: url,
cache: false,
headers: { 'X-SimpleProgress-TaskId': that._taskId },
success: function (data) {
if (that._taskCompletedCallback != null)
that._taskCompletedCallback(data);
that.end();
}
});
// Start the callback (if any)
if (that._userDefinedProgressCallback == null)
return this;
that._timerId = window.setTimeout(that._internalProgressCallback, that._interval);
};
// Finalize the task
that.end = function () {
that._taskId = 0;
window.clearTimeout(that._timerId);
}
return that;
}; |
SimpleProgress-Fx.js
|
20 |
При встраивании в готовый проект, после копирования всех необходимых файлов, и создания ссылок на них (например на скрипт SimpleProgress-Fx.js), необходимо переунаследовать контроллер, в котором будет происходить длительная операция, от класса SimpleProgressController. Поскольку он также унаследован от обычного Controller существующий код модифицировать не придется (кроме конечно же переунаследования). |
|
21 | На заметку: |
Единственный нюанс, на который необходимо обратить внимание, заключается в том, чтобы в существующем контроллере отсутствовал метод Progress, поскольку он будет конфликтовать с встроенным методом Progress родительского контроллера SimpleProgressController. Также, обязательно нужно проверить, чтобы существующие правила роутинга (процедура RegisterRoutes) давали доступ к этому методу, иначе клиент при обращении к этому методу не будет получать ответ.
|
|
22 |
Пример. У нас есть контроллер HomeController: |
|
23 | 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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 Imports Codius.Framework
Imports System.Threading
Public Class HomeController ... |
HomeController.vb
|
24 |
и представление View — метода Index: |
|
25 | 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 @Code
Layout Nothing
End Code
<!DOCTYPE html>
<html> ... |
Index.vbhtml
|
26 | На заметку: |
Файл проекта можно скачать по ссылке Codius.SimpleProgressBar_v1.0.rar (47,0 KB).
Проект создан в Visual Studio 2013 Ultimate.
|
|
27 |
Вдумчивые читатели могут узреть один существенный недостаток данной реализации — нельзя одновременно в кэш записывать данные и в текстовом формате, и в процентном. Можно, конечно, формировать единую строку, а потом на стороне клиента парсить её. Но это же не наш метод, поэтому внесем ряд конструктивных изменений в проект. |
|
28 |
О том как будет расширен функционал нашего ProgressBar — в статье Как сделать индикатор прогресса (ProgressBar) обновляющийся с сервера (ASP.NET, AJAX, JQuery) - часть 2 |
|
30 |
Похожие запросы:
|
|