Skip to main content

Источники данных

С помощью источников данных виджеты и боковые панели получают данные для отображения.

Стандартные источники получают данные от провайдеров данных, используя выборку. Существуют и другие способы получения данных: из локального хранилища браузера, значения по умолчанию, наследуемые источники и др. О каждом случае будет рассказано далее.

Местоположение источников

Источники задаются на странице <page> или в структуре приложения <application> с помощью элемента <datasources>.

Источники данных на странице

Наиболее частым случаем является задание источника на странице для заполнения виджета данными.

Источники данных на странице
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0">
<datasources>
<!-- Источники данных страницы -->
<datasource id="main"/>
<datasource id="docs"/>
<datasource id="addresses"/>
</datasources>
</page>

На такой источник данных можно сослаться из виджета с помощью атрибута datasource:

Ссылка на источник данных из виджета
<form datasource="main">
...
</form>
note

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

Вложенный источник данных в виджете

Источник данных можно создать внутри виджета, если данные нужны только этому виджету. В этом случае не нужно задавать идентификатор id источника, т.к. на него нельзя будет сослаться.

Вложенный источник данных виджета
<form>
<datasource>
<!-- Источник данных виджета -->
</datasource>
</form>
note

В качестве вложенного источника может использоваться только стандартный источник данных.

note

Если у виджета никак не задан источник данных, то он создастся автоматически.

Передача источника на открываемую страницу

Источники данных можно передать на открываемую страницу:

Передача источников данных на открываемую страницу
<button label="Создать">
<open-page page-id="personCard">
<datasources>
... <!-- Источники данных, которые будут переданы на страницу personCard -->
</datasources>
</open-page>
</button>

Или в модальное окно, и любые другие виды окон:

Передача источников данных в модальное окно
<button label="Создать">
<show-modal page-id="personCard">
<datasources>
... <!-- Источники данных, которые будут переданы на страницу personCard -->
</datasources>
</show-modal>
</button>

В случае, если id пробрасываемых источников не пересекаются с источниками открываемой страницы, то они просто дополнят список источников открываемой страницы.

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

Представим, что открываемая страница имеет следующий вид:

Открываемая страница
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0">
<datasources>
<datasource id="docs"/>
</datasources>

<regions>
<form datasource="docs">
<fields>
<input-text id="name" label="Наименование"/>
<input-text id="description" label="Описание"/>
</fields>
</form>
</regions>
</page>

Теперь откроем эту страницу сначала на создание (поля не будут заполнены):

Открытие страницы на создание Документа
<button label="Создать">
<show-modal page-id="docPage" page-name="Создание документа">
<datasources>
<datasource id="docs" default-values-mode="defaults"/>
</datasources>
</show-modal>
</button>

А после - на редактирование (поля заполнены значениями определенной записи):

Открытие страницы на изменение Документа
<button label="Изменить">
<show-modal page-id="docPage" page-name="Изменение документа">
<datasources>
<datasource id="docs" query-id="documents">
<filters>
<eq filter-id="id" value={id}/>
</filters>
<datasource/>
</datasources>
</show-modal>
</button>
note

Для передачи источника данных на страницу simple-page можно не задавать id. Он будет сливаться с единственным источником данных, который есть на странице.

note

В пробрасываемых источниках могут присутствовать ссылки на другие источники данных (например source-datasource в inherited-datasource). В таком случае считается, что эти источники заданы на открываемой странице. Если же вы хотели сослаться на источник родительской страницы, то укажите на открываемой странице parent-datasource.

Источники данных в приложении

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

Первая функция будет описана далее, а для второй существует специальный вид источника данных.

Для задания источников данных в приложении используется элемент datasources.

Источники данных в приложении
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<datasources>
<datasource id="appDs"/>
... <!-- Источники данных в приложении -->
</datasources>
</application>

На заданные таким образом источники можно ссылаться из боковых панелей <sidebar> с помощью атрибута datasource.

Ссылка на источник данных из боковой панели
<sidebar datasource="appDs">
...
</sidebar>

Источник данных в боковой панели <sidebar> позволяет отображать динамические данные в заголовках или ссылках навигационного меню.

note

Из разных боковых панелей можно ссылаться на один и тот же источник данных. В этом случае они все будут оперировать одними и теми же данными.

Источник данных можно создать внутри боковой панели, если данные нужны только этой боковой панели. В этом случае не нужно задавать идентификатор id источника, т.к. на него нельзя будет сослаться.

Вложенный источник данных в боковой панели
<sidebar>
<datasource>
<!-- Источник данных боковой панели -->
</datasource>
</sidebar>
note

В качестве вложенного источника может использоваться только стандартный источник данных.

note

Если у боковой панели не задан источник данных, то он создастся автоматически.

Виды источников данных

Стандартный источник данных

В стандартном источнике данных можно задать объект и выборку, чтобы загружать и сохранять данные через провайдеры.

Выборка и объект стандартного источника данных
<datasource id="main"
object-id="person"
query-id="person">
...
</datasource>

Фильтрация источника данных

Выборку можно отфильтровать через элемент <filters>.

Фильтры источника данных
<datasource id="main" query-id="person">
<filters>
<eq field-id="id" value="123"/>
... <!-- Другие фильтры выборки -->
</filters>
</datasource>

Подробнее о фильтрации выборок

Отправка данных формы

Данные формы можно сохранить через стандартный источник данных с помощью элемента <submit>.

Задание операции при отправке данных
<datasource id="main"
object-id="person">
<submit operation-id="save"/>
</datasource>

Атрибутом operation-id задается ссылка на операцию объекта, которая вызовется при отправке данных.

Отправка данных формы может быть вызвана по кнопке.

Кнопка отправки данных формы
<button label="Сохранить">
<submit datasource="main"/>
</button>

Можно отправлять данные формы автоматически при каждом изменении полей формы.

Отправка данных формы при изменении полей
<datasource id="main" object-id="person">
<submit auto="true" operation-id="save"/>
</datasource>

Это задается с помощью атрибута auto. По умолчанию выключено.

Валидация источника данных

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

Вызов валидации по кнопке
<button label="Сохранить"
validate="true"
validate-datasource="main, docs, addresses">
... <!-- Действие -->
</button>

С помощью атрибута validate-datasources можно указать источники данных, которые требуется провалидировать перед вызовом действия.

Подробнее о валидации

Значения по умолчанию в источниках данных

Значения по умолчанию задаются в полях формы через атрибут default-value.

<input-text id="firstName" default-value="Joe"/>

Но также можно комбинировать значения по умолчанию и данные, полученные через выборку. Для этого необходимо настроить правила слияния с помощью атрибута default-values-mode.

Cлияние выборки и значений по умолчанию
<datasource id="main"
query-id="person"
default-values-mode="merge">
...
</datasource>

Правила слияний

ПравилоОписание
mergeЗначения по умолчанию заполняются путем слияния данных, прописанных в полях и полученных из запроса (полученные из запроса в приоритете).
queryЗначения по умолчанию заполняются данными из запроса. Значения по умолчанию игнорируются.
defaultsЗначения по умолчанию заполняются значениями по умолчанию. Выборка не вызывается.

Подробнее о значениях по умолчанию

Подробнее о стандартном источнике данных

Браузерное хранилище

Элемент <browser-storage> позволяет получать и сохранять данные в localStorage или sessionStorage браузера.

Удобство браузерного хранилища заключается в том, что при закрытии вкладки или перезагрузке, данные не будут потеряны.

Источник данных браузерного хранилища
<datasources>
<browser-storage id="main"
key="n2o.storage.main"
type="sessionStorage">
...
</browser-storage>
</datasources>

Атрибут key задает пространство в браузерном хранилище, в котором будут сохраняться данные.

Сохранение данных в браузерное хранилище

Данные формы можно сохранить в браузерное хранилище с помощью элемента <submit>.

Задание операции при отправке данных
<browser-storage id="main"
key="n2o.storage.main"
type="sessionStorage">
<submit auto="true"
model="resolve"/>
</browser-storage>

Атрибут model в элементе <submit> определяет модель данных, которая будет сохраняться в хранилище браузера.

Подробнее о браузерном хранилище

Кэширующий источник данных

Элемент <cached-datasource> - объединение обычного источника данных с браузерным хранилищем. При загрузке страницы идет проверка есть ли данные в кэше браузера. Если нет, идет запрос за данными на сервер.

Удобство браузерного хранилища заключается в том, что при закрытии вкладки или перезагрузке, данные не будут потеряны. Более того этот источник позволяет выполнять "тяжелые" запросы на сервер только однократно, получая в дальнейшем данные из браузерного кэша.

Кэширующий источник данных
<cached-datasource id="ds1" storage-key="test_key"
invalidate-cache-path-params="person_id"
query-id="person"
cache-expires="1d">
<filters>
<eq field-id="id" param="person_id"/>
</filters>
<submit clear-cache-after-submit="true"/>
</cached-datasource>

Время жизни кэша

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

Но с помощью атрибута cache-expires есть возможность задавать время жизни кэша. Если с момента последнего запроса данных прошло время большее его значения, то данные будут запрошены с сервера повторно.

Атрибут задается в формате 1d 3h 2m, где число перед

  • d - количество дней
  • h - количество часов
  • m - количество минут

Каждый из параметров является необязательным, поэтому можно задавать любую комбинацию с использованием нескольких из них, например 2d 15m или 12h.

Инвалидация кэша

Атрибуты invalidate-cache-path-params и invalidate-cache-query-params также влияют на актуальность кэша. Приведем пример с invalidate-cache-path-params="person_id" и урлом страницы /open/:person_id.
Если мы зайдем на страничку по урлу /open/1, то сначала данные будут получены с сервера. При обновлении страницы или при повторном возврате на этот урл данные будут запрошены уже с браузерного хранилища.
Но после того, как мы зайдем на страничку с урлом /open/2, это будет признаком для источника данных, что нужно заново актуализировать данные. Будет произведен новый запрос на сервер и данные в кэше по person_id=1 будут полностью заменены данными по person_id=2.

Наследуемый источник данных

Источники данных могут получать данные путем копирования из других источников. Такие источники называются наследуемыми и задаются элементом <inherited-datasource>.

Наследуемый источник данных
<datasources>
<inherited-datasource id="docs"
source-datasource="person"
source-model="resolve"
source-field-id="docs">
...
</inherited-datasource>
</datasources>

Атрибуты source-* задают ссылку на родительский источник данных.

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

Наследуемый источник данных
<datasources>
<datasource id="person"
query-id="person"
size="1"/>

<inherited-datasource id="docs"
source-datasource="person"
source-model="resolve"
source-field-id="docs"/>
</datasources>
note

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

Можно заставить виджет принудительно скопировать данные через действие <refresh>:

<button label="Обновить">
<refresh datasource="docs"/>
</button>

Либо использовать зависимость обновления данных:

<datasources>
<datasource id="person"
query-id="person"
size="1"/>

<inherited-datasource id="docs"
source-datasource="person"
source-model="resolve"
source-field-id="docs">
<dependencies>
<fetch on="ds1"/>
</dependencies>
</inherited-datasource>
</datasources>

Подробнее о наследуемом источнике данных

Stomp источник данных

Stomp источник данных получает данные с помощью STOMP протокола и задается элементом <stomp-datasource>.

Задание Stomp источника для получения счетчика и цвета
<datasources>
<stomp-datasource id="notifCount"
destination="/notif">
...
</stomp-datasource>
</datasources>

Атрибут destination определяет очередь сообщений, на которую подписывается источник данных.

note

Наиболее частым случаем применения Stomp источника данных является асинхронное получение счетчиков.

Задание Stomp источника для получения счетчика и цвета
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<datasources>
<!-- клиент будет прослушивать данные, полученные по указанному destination -->
<stomp-datasource id="notifCount" destination="/notif">
<values>
<!-- значение счетчика на момент инициализации -->
<value count=""/>
<!-- цвет значка на момент инициализации -->
<value color="success"/>
</values>
</stomp-datasource>
</datasources>
...
</application>

С помощью <values> задаются значения при старте приложения, когда данные из STOMP еще не были получены.

Использовать Stomp источник данных можно в меню навигации.

Использование счетчика и цвета в элементах страницы
<application>
<header title="Хедер">
<nav>
<!-- элемент меню, в котором отобразится обновленное значение счетчика и изменится цвет значка-->
<!-- атрибут должен ссылаться на имя поля, используемого в stomp-datasource (в данном случае count и color) -->
<menu-item id="notif"
icon="fa fa-bell"
datasource="notifCount"
badge="{count}"
badge-color="{color}">
...
</menu-item>
</nav>
</header>
</application>

Подробнее о stomp источниках данных

Источник данных приложения на странице

На источник данных, заданный в структуре приложения, можно сослаться из виджетов страницы. Для этого нужно на странице определить специальный источник данных <app-datasource>.

Источник данных на странице, заданный в структуре приложения
<page>
<datasources>
<app-datasource id="appDs"/> <!-- Ссылка на источник данных в приложении -->
</datasources>

<regions>
<form datasource="appDs"/> <!-- Ссылка на app-datasource -->
</regions>
</page>

Где id - это ссылка на идентификатор источника в приложении.

note

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

note

Элемент app-datasource нельзя использовать в application.xml.

Прокидывание разных app-datasource из родительской страницы

Если необходимо открывать модальное окно с разными источниками данных приложения, то в app-datasource можно воспользоваться атрибутом source-datasource. В таком случае атрибут id будет играть роль уникального идентификатора, а source-datasource - идентификатор источника из application.xml. Это позволит под одним id прокидывать ссылки на разные источники.

Родительская страница
<page>
<toolbar>
<button label="Btn1">
<show-modal page-id="modal">
<datasources>
<app-datasource id="parentDS" source-datasource="docs1"/> <!-- ссылается на данные из docs1 -->
</datasources>
</show-modal>
</button>
<button label="Btn2">
<show-modal page-id="modal">
<datasources>
<app-datasource id="parentDS" source-datasource="docs2"/> <!-- ссылается на данные из docs2 -->
</datasources>
</show-modal>
</button>
</toolbar>
</page>
Открываемая страница
<page>
<datasources>
<app-datasource id="parentDS"/>
</datasources>

<regions>
<form datasource="parentDS"/>
</regions>
</page>

Подробнее об источниках данных приложения на странице

Источник данных родительской страницы

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

Для этого нужно на странице определить специальный источник данных <parent-datasource>.

Источник данных, ссылающийся на источник данных родительской страницы
<page>
<datasources>
<parent-datasource id="docs"/> <!-- Ссылка на источник данных родительской страницы -->
</datasources>

<regions>
<form datasource="docs"/> <!-- Ссылка на parent-datasource -->
</regions>
</page>

Где id - это ссылка на идентификатор источника родительской страницы.

note

В случае, если понадобится с N-ой страницы сослаться на источник данных первой страницы, то необходимо последовательно указать parent-datasource, начиная со 2-ой страницы и далее.

note

Элемент parent-datasource нельзя использовать в application.xml.

Прокидывание разных parent-datasource из родительской страницы

Если необходимо открывать одно модальное окно с разными родительскими источниками данных, то в parent-datasource можно воспользоваться атрибутом source-datasource. В таком случае атрибут id будет играть роль уникального идентификатора, а source-datasource - идентификатор источника родительской страницы. Это позволит под одним id прокидывать ссылки на разные источники.

Родительская страница
<page>
<datasources>
<datasource id="docs1"/>
<datasource id="docs2"/>
</datasources>

<toolbar>
<button label="Btn1">
<show-modal page-id="modal">
<datasources>
<!-- ссылается на данные из docs1 -->
<parent-datasource id="parentDS" source-datasource="docs1"/>
</datasources>
</show-modal>
</button>
<button label="Btn2">
<show-modal page-id="modal">
<datasources>
<!-- ссылается на данные из docs2 -->
<parent-datasource id="parentDS" source-datasource="docs2"/>
</datasources>
</show-modal>
</button>
</toolbar>
</page>
Открываемая страница
<page>
<datasources>
<parent-datasource id="parentDS"/>
</datasources>

<regions>
<form datasource="parentDS"/>
</regions>
</page>

Подробнее об источниках данных родительской страницы

Зависимости источников данных

В источнике данных можно добавить зависимости на изменения других источников данных. Зависимости задаются в элементе <dependencies>.

Зависимости источника данных
<datasource>
<dependencies>
... <!-- Зависимости источника данных -->
</dependencies>
</datasource>

Зависимость обновления данных

Если требуется обновить текущий источник данных при изменении в другом источнике, нужно добавить зависимость <fetch>.

Зависимость обновления данных
<datasources>
<datasource id="main"/>

<datasource id="docs" query-id="docs">
<dependencies>
<!-- При изменении resolve модели источника main будет выполнен запрос выборки docs -->
<fetch on="main" model="resolve"/>
</dependencies>
</datasource>
</datasources>

Зависимость копирования данных

Если требуется скопировать данные из другого источника, нужно добавить зависимость copy.

Зависимость копирования данных
<datasources>
<datasource id="docs" query-id="docs"/>

<datasource id="card">
<dependencies>
<!-- При изменении resolve модели источника main будут скопированы данные поля number в поле phone -->
<copy on="main"
source-model="resolve"
source-field-id="number"
target-model="resolve"
target-field-id="phone"/>
</dependencies>
</datasource>
</datasources>
note

Если не указывать target-field-id или source-field-id, то будет копироваться вся модель.

Подробнее о зависимостях источников данных

Модели данных

Источник данных загружает данные на клиент в формате json и перемещает их в Redux хранилище с ключем models.[model].[page_datasource], где

  • page - адрес страницы,
  • datasource - идентификатор источника данных страницы,
  • model - модель данных.

У источника данных может быть несколько моделей:

Модели данных

МодельОписаниеПример
datasourceВсе загруженные записиСписок записей у таблицы
resolveТекущая записьВыделенная запись таблицы
filterЗначения фильтровЗначения фильтров таблицы, заданные пользователем
multiВсе выделенные записиПомеченные чекбоксы в таблице
editНе сохраненные данныеФорма, открытая на редактирование, с изменёнными полями

На модель данных можно ссылаться, например, в зависимостях или в фильтрах:

Ссылка на модель данных в фильтрах
<datasource id="docs"
query-id="docs">
<filters>
<!-- Фильтр со значением, взятым из источника main с моделью resolve -->
<eq field-id="person.id"
value="{id}"
datasource="main"
model="resolve"/>
</filters>
</datasource>

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

Ссылка на модель данных в действиях
<button>
<!-- Вызов операции с данными из источника docs с моделью resolve -->
<invoke operation-id="delete"
datasource="docs"
model="resolve"/>
</button>