Содержание

DataFlow - Потоки данных при использовании PullView и WACT шаблонов. Взаимодействие различных компонентов

Поток данных, при выполнении запроса из шаблона

Большинство шаблонов Limb используют шаблоны WACT и реализованы по схеме PullView, то есть шаблоны самостоятельно вытягивают данные из модели. Попробуем описать, каким образом данные вытягиваются, какие это включает этапы, и какие классы в этом участвуют.

Также рекомендуется посмотреть следующие страницы:

На данной странице предпринята попытка объединить все эти знания в одно целое. Также рекомендуется посмотреть описание, работу и код базового туториала по архитектуре Limb, в рамках которого создается и выводится простенькая лента новостей.

Итак:

Шаблон

Итак, допустим у нас есть вот такой шаблон:

[...]
 
<fetch using="{LKPG_WEB_APP_DIR}/src/fetcher/lmbTableRecordsFetcher" pass_to="news">
  <fetch:param table_name='news' order='date=DESC,title=ASC'>
</fetch>
 
<list:LIST id="news">
  <table border="0">
  <list:ITEM>
  <tr>
    <td>
    <b>{$date}</b>
    </td>
    <td>
    <b>{$title}</b>
    </td>
  </tr>
  </list:ITEM>
  </table>
</list:LIST>

Суть данного шаблона - в отображении списка новостей из таблицы news

При рендеринге данного шаблона будет создан экземпляр lmbTableRecordsFetcher, у данного объекта будет вызван метод getDataSet(), который вернет набор данных (итератор), и этот набор данных будет передан в компонент шаблона news (см. атрибут pass_to тега <fetch>), который выводит список. Подробнее о работе lmbFetcher-ов.

<list:list> тег, который занимается выводом списковых данных, таким образом получит данные из базы данных. Мы не будем вдаваться в подробности того, как итератор будет использоваться внутри шаблона. Скажем, что при помощи методов интерфейса Iterator шаблон пробегает по набору данных, каждую запись из набора помещает внутрь контейнера данных тега <list:item>. Тег <list:item> в свою очередь выводит данные из своего контейнера данных, например, при помощи конструкций вида {$title} или {$date}. см. введение в шаблонную систему WACT

Работа lmbFetcher-ов

Теперь перейдем к lmbTableRecordsFetcher, который использовался в шаблоне. lmbTableRecordsFetcher наследуется от lmbQueryBasedFetcher, который делает запросы к базе данных при помощи классов из пакета DBAL.

Основной параметр, который используется при работе с lmbTableRecordsFetcher - это название класса table_name, в нашем случае это news, в которых хранятся новости. При помощи lmbTableGateway используемый fetcher lmbTableRecordsFetcher создает объект класса lmbSelectQuery, который будет отвечать за формирование SQL-запроса к базе данных.

Итак, когда мы вызвали (неявно) в шаблоне метод lmbTableRecordsFetcher :: getDataSet() для передачи данных в список шаблона, произошло следующее:

  1. lmbQueryBasedFetcher вызвал метод _createQuery(), который перекрыт в lmbTableRecordsFetcher
  2. создался экземпляр lmbTableGateway, куда передалось название таблицы news;
  3. lmbTableGateway создал экземпляр lmbSelectQuery, который будет использоваться далее в lmbQueryBasedFetcher; Этот объект вернутся из метода _createQuery().
  4. lmbQueryBasedFetcher далее создал при помощи DBAL-а новый объект-statement на основе того SQL-кода, который получен из метода lmbSelectQuery :: toString();
  5. из statementа был получен итератор, который инкапсулирует результат запроса к базе данных.
  6. этот итератор был передан в шаблон для отображения.

Обратите внимание, что когда итератор был передан в шаблон - запрос к базе данных еще не был сделан. От будет сделан только после вызова метода Iterator :: rewind() итератора.

Альтернативный способ или посмотрим поглубже

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

Ниже будет дан код, который позволит сделать все тоже самое, но вручную. Это позволит также прояснить все вышесказанное.

Допустим у нас есть команда, которая должна отобразить список новостей. Вот как это бы выглядело, если бы мы передавали данные в шаблоны вручную:

  $SQL = 'SELECT * FROM news ORDER BY date DESC, title ASC';
  $connection = lmbToolkit :: instance()->getDbConnection();
  $stmt = $connection->newStatement($sql);
  $news_record_set = $stmt->getRecordSet();
 
  $template = new Template('news/display.html');
  $list_component = $template->getChild('news');
  $list_component->registerDataSet($news_record_set);

Пример такого кода есть в скрипте last_news_rss.php, который можно найти в папке LPKG_WEB_APP_DIR/examples/crud. При помощи этого скрипта формируется RSS-feed для ленты новостей базового туториала