JavaScript выражения
В N2O можно использовать JavaScript выражения для вычисления значений на основе текущей модели данных.
Такие выражения применяются для:
JavaScript выражение должно возвращать значение, которое будет использовано фреймворком.
Описывать выражения можно двумя способами:
- В атрибутах элементов, обернув JavaScript код в фигурные скобки:
{/* javascript */}
<output-text id="randomNum" default-value="{Math.random()}"/>
- В теле предназначенных для этого тэгов
<output-text id="randomNum">
<dependencies>
<set-value apply-on-init="true">
Math.random()
</set-value>
</dependencies>
</output-text>
<output-text id="randomNum">
<dependencies>
<set-value apply-on-init="true">
const value = Math.random()
return "default-value=" + value
</set-value>
</dependencies>
</output-text>
Контекст выполнения и область видимости
Контекст выполнения (this) указывает на модель данных, связанную с компонентом.
<output-text id="fullName" default-value="{this.firstName + ' ' + this.lastName}"/>
Область видимости выражения расширена дополнительными утилитами и данными, которые зависят от места использования выражения.
Также для более короткой записи, поля модели данных доступны в области видимости выражения
<output-text id="fullName" default-value="{firstName + ' ' + lastName}"/>
Глобальная область видимости
Утилиты, подключенные на уровне приложения и доступные в любом месте
| Доступ | Описание |
|---|---|
| $ | Утилиты N2O |
| _ | https://lodash.com/ |
| moment | https://momentjs.com/ |
| numeral | http://numeraljs.com/ |
<output-text id="moment" default-value="{moment('06.02.2019').format('DD.MM.YYYY')}"/> <!-- 02.06.2019 -->
<output-text id="numeral" default-value="{numeral(1.5).format('0.000')}"/> <!-- 1,500 -->
<output-text id="lodash" default-value="{_.join(['a', 'b', 'c'], '~')}"/> <!-- a~b~c -->
Утилиты N2O
Набор вспомогательных и часто используемых функций
| Функция | Описание | Тип |
|---|---|---|
| $.uuid | Генерация uuid | () => string |
| $.isEmptyModel | Проверяет, пустая ли модель | (model?: object) => boolean |
| $.now | Текущая дата и время | (format?: string) => string |
| $.today | Текущая дата | (format?: string) => string |
| $.beginWeek | Начало недели | (format?: string) => string |
| $.endWeek | Конец недели | (format?: string) => string |
| $.beginMonth | Начало месяца | (format?: string) => string |
| $.endMonth | Конец месяца | (format?: string) => string |
| $.beginQuarter | Начало квартала | (format?: string) => string |
| $.endQuarter | Конец квартала | (format?: string) => string |
| $.beginYear | Начало года | (format?: string) => string |
| $.endYear | Конец года | (format?: string) => string |
<date-time id="dt" default-value="{$.now()}"/>
Виджеты
В выражениях доступны дополнительные данные, возвращённые сервером с помощью атрибута additional-mapping элемента <list>.
| Доступ | Описание |
|---|---|
| $additionalInfo | Дополнительная информация |
<list result-mapping="['messages.data']" additional-mapping="['messages.count']">
...
<list>
{
"meta": {},
"list": [...],
"paging": {},
"additionalInfo:" {
"all": 5,
"new": 2,
"archived": 3
}
}
<toolbar>
<button label="Все ({ $additional.all })"/>
<button label="Непрочитанные ({ $additional.new })"/>
<button label="В архиве ({ $additional.archived })"/>
</toolbar>
Контекст this
Зависит от используемой модели виджета
Мультисет
| Доступ | Описание |
|---|---|
| index | Номер строки мультисета. Также можно использовать $index_0 |
| $index_N | Номер строки при использовании вложенных друг в друга мультисетов, где N - уровень вложенности, начиная с 0 |
<multi-set id="items">
<output-text id="fullName" label="Участник №{index}" default-value="{items[index].firstName + ' ' + items[index].lastName}"/>
<multi-set id="results">
<output-text id="score" label="Результат забега №{$index_1}" />
</multi-set>
</multi-set>
Ограничени я
Контекст выполнения
Т.к. все выражения должны быть синхронными и возвращать значение, зависящее только от модели данных, из глобального контекста выполнения убраны доступы к api, позволяющим создавать сайд-эффекты.
Среда выполнения
⚠ Ограничение серверной проверки
Выражения, используемые в валидации, выполняются не только на клиенте, но и на сервере
из-за заданного значения для атрибута side="client,server".
На сервере выражения обрабатывает библиотека Nashorn. Поэтому необходимо использовать синтаксис ECMAScript 5.
Некоторые возможности современного JavaScript могут быть недоступны:
- стрелочные функции
- optional chaining
- nullish coalescing
return person?.items.filter(({ value }) => (value)) ?? []
return person && person.items.filter(function(item) { return item.value }) || []
Спецсимволы в xml
Из-за особенностей формата, символы вроде & < внутри javascript выражений могут привести к поломке синтаксиса документа,
поэтому их необходимо заменять на HTML-сущности & <
либо обернуть JavaScript код в блок CDATA: <![CDATA[/* javascript */]]>
<output-text id="allow" class="{age && (18 <= age) ? 'success' : 'warn'}" >
<dependencies>
<set-value apply-on-init="true">
<![CDATA[
age && (18 <= age)
]]>
</set-value>
</dependencies>
</output-text>