Использование веб-контрола для отображения часто обновляемых данных

Опубликовано:
27 ноября в 12:40
  • 0

Возникают ситуации, когда пользователю необходимо отображать часто меняющиеся данные. Например, процесс обработки документов на сервере. С периодичностью 2 секунды информация об обработанных документах должна подгружаться в фоновом режиме и отображаться пользователю в виде таблицы. То есть пользователь должен видеть “живую” картину происходящего, и у него должна быть возможность влиять на ход какого-либо процесса. Стандартные элементы интерфейса в таком случае нам не подойдут, но можно использовать замечательный элемент управления Веб-браузер (STWebBrowserControl)

Как все будет работать:

  1. На событии Показ диалога, генерируем HTML-страницу.
  2. Открываем HTML через STWebBrowserControl, пользователю отображается таблица.
  3. Таймер в JavaScript будет периодически инициировать обновление данных, вызывая метод диалога.

Генерация HTML документа 

Тело HTML страницы будет состоять из одной пустой таблицы.

<table cellspacing="0">
  <thead>
  <tr>
  <th>Процесс обработки</th>
  <th>Ошибки</th>
  <th style="width: 100px">Обработано</th>
  <th style="width: 75px"></th>
  </tr>
  </thead>
  <tbody id = "mytable">
  </tbody>
</table>

Данными эту таблицу будем заполнять в JS, первый раз на событие window.onload и далее по таймеру через 2 секунды.

Для этого необходимо получить таблицу

tableElement = document.getElementById("mytable");

И получить объект диалога для последующего обращения к его методам

myDialog = window.external.Form.View.Component;

Вызвать функцию UpdateTable() с рекурсией через setTimeout. В этой функции будем обновлять свойство innerHTML у tableElement

Полный код JavaScript для десктопа

  var myDialog;
  var tableElement;
  
  function Init() {
	 tableElement = document.getElementById("mytable"); 
	 myDialog = window.external.Form.View.Component;      
	 UpdateTable();
  } 

  function UpdateTable() {
	 try {        
		tableElement.innerHTML = myDialog.GetTableData();
		setTimeout(UpdateTable, 2000);
	 } 
	 catch(ex) {
		
	 }          
  }
  
  window.onload = Init;

В вебе window.external.Form.View.Component вернет ошибку,  чтобы наш диалог заработал, при создании необходимо передать InstanceID диалога в качестве параметра методу GenerateHTML, и в JS получить диалог уже через getDialogByInstanceID

Подробнее реализацию диалога можно посмотреть в примере ниже.

Метод диалога GetTableData возвращает HTML-код таблицы, сгенерированный SQL запросом. Для примера заполним HTML-таблицу случайными значениями

select 
  (select cName as 'td' for xml path(''), type),
  (select cError as 'td' for xml path(''), type),
  (select (cDoc * 100 / cDocCount) as 'img/@width', (cast(cDoc as varchar) + '/' + cast(cDocCount as varchar)) as 'div' 
  for xml path('div'), elements, type) as 'td',
  (select 'javascript:CancelProcess('+char(34)+cName+char(34)+');' as 'a/@href', 'Отменить' as 'a' 
  for xml path('td'), elements, type) 
from 
  (VALUES ('Обработка документов № 0', cast((RAND()*10) as int), cast((RAND()*80) as int), 180),
	      ('Обработка документов № 1', cast((RAND()*10) as int), cast((RAND()*20) as int), 40),
		  ('Обработка документов № 2', cast((RAND()*10) as int), cast((RAND()*200) as int), 360),
		  ('Обработка документов № 3', cast((RAND()*10) as int), cast((RAND()*150) as int), 250),
		  ('Обработка документов № 4', cast((RAND()*10) as int), cast((RAND()*100) as int), 170)   
  ) v(cName, cError, cDoc, cDocCount)
for xml path('tr')

Результат запроса будет выглядеть так:

<tr>
  <td>Обработка документов № 0</td>
  <td>9</td>
  <td>
    <div>
      <img width="7" />
      <div>14/180</div>
    </div>
  </td>
  <td>
    <a href="javascript:CancelProcess(&quot;Обработка документов № 0&quot;);">Отменить</a>
  </td>
</tr>
.
.
.

Для корректной работы STWebBrowserControl в веб, в диалог необходимо еще передать  URL-адрес папки пользователя и локальный путь до папки пользователя в IIS. Локальный путь понадобится, чтобы сохранить HTML-файл, а URL-адрес папки – чтобы открыть HTML в браузере.

Вызов диалога из веба, для тестирования можно вставить код в консоль javascript (Ctrl + Shift + J):

WA.SRV.call("BaseService.asmx/GetUserFolderName", {}).done(function (data) {
	var relativePath = data[0];
	var localuserFolder = data[1];
	var params = {};
	var path = "http://" + window.location.host + relativePath;
	params['String2'] = path;
	params['String'] = localuserFolder;
	WA.SRV.call("BaseService.asmx/CreateDialogWithParams", { DialogName: "_test_MyDialog", Params: params }).done(function (dialogInstanceID) {
		WA.FC.dialogs.getDialogByInstanceID(dialogInstanceID).done(function (dialog) {
			dialog.executeEntityMethod('GenerateHTML', dialogInstanceID).done(function () {
				dialog.show();
				dialog.executeEntityMethod('OpenHTML').done(function () { });
			});
		});
	}).fail(function (message) {
		WA.CR.inlineHint.showError(message);
	});
}).fail(function (message) {
	WA.CR.inlineHint.showError(message);
});

В результате мы получили обновляемую в фоновом режиме таблицу, которая будет работать в десктопе и вебе.


Подробнее реализацию диалога можно посмотреть в примере _test_mydialog.zip

15
Подписаться

Комментарии

Пока комментариев нет
Авторизуйтесь, чтобы написать комментарий