====== DataFlow - Потоки данных при использовании PullView и WACT шаблонов. Взаимодействие различных компонентов ======
===== Поток данных, при выполнении запроса из шаблона =====
Большинство шаблонов Limb используют шаблоны WACT и реализованы по схеме [[PullView]], то есть шаблоны самостоятельно вытягивают данные из модели. Попробуем описать, каким образом данные вытягиваются, какие это включает этапы, и какие классы в этом участвуют.
Также рекомендуется посмотреть следующие страницы:
* [[limb3_2007_2:ru:packages:datasource|Описание пакета DATASOURCE]] - важно четко уяснить, что такое итераторы.
* Что такое [[lmbFetcher]]-ы.
* Основные принципы работы [[limb3_2007_2:ru:template_system|шаблонной системы WACT]].
* [[limb3_2007_2:ru:packages:dbal|Описание пакета DBAL]].
На данной странице предпринята попытка объединить все эти знания в одно целое. Также рекомендуется посмотреть описание, работу и код [[limb3_2007_2:ru:tutorials:basic|базового туториала по архитектуре Limb]], в рамках которого создается и выводится простенькая лента новостей.
Итак:
==== Шаблон ====
Итак, допустим у нас есть вот такой шаблон:
[...]
Суть данного шаблона - в отображении списка новостей из таблицы news
При рендеринге данного шаблона будет создан экземпляр [[lmbTableRecordsFetcher|lmbTableRecordsFetcher]], у данного объекта будет вызван метод getDataSet(), который вернет набор данных (итератор), и этот набор данных будет передан в компонент шаблона news (см. атрибут pass_to тега [[limb3_2007_2:ru:template_system:tags:lmb_fetch_tags:lmb_fetch_tag|]]), который выводит список. [[lmbFetcher|Подробнее о работе lmbFetcher]]-ов.
[[limb3_2007_2:ru:template_system:tags:list_tags:list_list_tag|]] тег, который занимается выводом списковых данных, таким образом получит данные из базы данных. Мы не будем вдаваться в подробности того, как итератор будет использоваться внутри шаблона. Скажем, что при помощи методов интерфейса Iterator шаблон пробегает по набору данных, каждую запись из набора помещает внутрь контейнера данных тега [[limb3_2007_2:ru:template_system:tags:list_tags:list_item_tag|]]. Тег [[limb3_2007_2:ru:template_system:tags:list_tags:list_item_tag|]] в свою очередь выводит данные из своего контейнера данных, например, при помощи конструкций вида {$title} или {$date}. см. [[limb3_2007_2:ru:template_system:intro|введение в шаблонную систему WACT]]
==== Работа lmbFetcher-ов ====
Теперь перейдем к [[lmbTableRecordsFetcher]], который использовался в шаблоне. lmbTableRecordsFetcher наследуется от [[lmbQueryBasedFetcher]], который делает запросы к базе данных при помощи классов из [[limb3_2007_2:ru:packages:dbal|пакета DBAL]].
Основной параметр, который используется при работе с [[lmbTableRecordsFetcher]] - это название класса table_name, в нашем случае это news, в которых хранятся новости. При помощи [[limb3_2007_2:ru:packages:dbal:lmbTableGateway|lmbTableGateway]] используемый fetcher [[lmbTableRecordsFetcher]] создает объект класса [[limb3_2007_2:ru:packages:dbal:lmbSelectQuery|lmbSelectQuery]], который будет отвечать за формирование SQL-запроса к базе данных.
Итак, когда мы вызвали (неявно) в шаблоне метод lmbTableRecordsFetcher :: getDataSet() для передачи данных в список шаблона, произошло следующее:
- [[lmbQueryBasedFetcher]] вызвал метод _createQuery(), который перекрыт в [[lmbTableRecordsFetcher]]
- создался экземпляр [[limb3_2007_2:ru:packages:dbal:lmbTableGateway|lmbTableGateway]], куда передалось название таблицы //news//;
- [[limb3_2007_2:ru:packages:dbal:lmbTableGateway|lmbTableGateway]] создал экземпляр [[limb3_2007_2:ru:packages:dbal:lmbSelectQuery|lmbSelectQuery]], который будет использоваться далее в [[lmbQueryBasedFetcher]]; Этот объект вернутся из метода _createQuery().
- [[lmbQueryBasedFetcher]] далее создал при помощи [[limb3_2007_2:ru:packages:DBAL|DBAL]]-а новый объект-statement на основе того SQL-кода, который получен из метода lmbSelectQuery :: toString();
- из statementа был получен итератор, который инкапсулирует результат запроса к базе данных.
- этот итератор был передан в шаблон для отображения.
Обратите внимание, что когда итератор был передан в шаблон - запрос к базе данных еще не был сделан. От будет сделан только после вызова метода 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 для ленты новостей [[limb3_2007_2:ru:tutorials:basic|базового туториала]]