Инструкция используется для определения возможных значений биндинга в атрибуте class
.
По умолчанию для биндингов в атрибуте class
используются простые правила, которые, тем не менее, могут приводить к непредсказуемому результату и не всегда безопасны. Например:
<div class="{example}"/>
В этом случае, если значение биндинга {example}
является true
, то в качестве имени класса будет использоваться example
, а для значения foo
имя класса будет foo
. Инструкция <b:define>
позволяет задать более строгие правила и определить конечный список используемых значений.
В следующем примере для example
задан тип bool
. Это значит, что независимо от значения биндинга example
оно будет приводиться к boolean
. Тем самым гарантируется, что у <div>
либо будет класс example
, либо ни одного класса.
<b:define name="example" type="bool"/>
<div class="{example}"/>
Знание о возможных значениях биндинга в атрибуте class
позволяет:
-
получать предсказуемый список имен имена классов
-
находить соответствия между именами классов в шаблонах и стилях, для обнаружения неиспользуемого CSS и классов в шаблонах, для которых нет стилей
Этим занимается инструмент
basisjs-tools
(а точнее его частьbasisjs-tools-build
). Список проблем можно получить в консоли командойbasis lint
или в плагине. -
безопасно минизировать имена классов при сборке приложения
Если все имена классов зафиксированы, сборщику можно указать флаг
--css-optimize-names
и тогда он минимизирует имена классов в шаблонах иCSS
(до одно-/двух-буквенных), тем самым уменьшив размер сборки. -
обнаруживать конфликты, когда одинаковые имена классов могут быть образованы разными биндингами, что может привести к ошибкам
На данных момент такая проверка не делается, но она должна быть добавлена.
Основные атрибуты:
name
– имя значения, для которого описывается правилоfrom
(опционально) – имя биндинга, который является источником значенияtype
– тип получаемого значенияdefault
(опциональный) – значение по умолчанию
Другие атрибуты зависят от заданного типа.
Задает имя определения. Это имя должно быть валидным идентификатором и используется в качестве имени биндинга в разметке, но только для атрибута class
. По сути инструкция переопределяет биндинг для атрибута class
.
В случае отсутствия атрибута from
, значение атрибута так же является именем биндинга, чье значение тестируется. Если определение имеет тип bool
или invert
, то имя используется в качестве имени класса.
Атрибут позволяет задать имя биндинга, в случае если имя определения и биндинга не совпадают. В качестве значения используются только оригинальные биндинги передаваемые в шаблон. Определения объявленные с помощью <b:define>
не учитываются.
Один из способ использования – переименование биндинга:
<b:define name="active" from="selected" type="bool"/>
<div class="{active}"/>
В данном примере, если selected == true
у <div>
будет класс active
, иначе класса не будет.
Атрибут определяет тип значения и может принимать следующие значения:
bool
– приведение значения кboolean
invert
– инверсия значенияenum
– фиксированный список значений
Данный тип задает приведение значения биндинга к boolean
. Если значение тождественно true
, то вставляется имя класса, которое соотвествует значению атрибута name
. В противном случае класс не вставляется.
<b:define name="foo" type="bool"/>
<div class="example {foo} prefix_{foo}"/>
Без установки значения биндингу:
<div class="example"></div>
foo == true
:
<div class="example foo prefix_foo"></div>
foo != true
:
<div class="example"></div>
Противоположность типу bool
. Исходное значение приводится к boolean
и инвертируется. Имя класса, которое соотвествует значению атрибута name
, вставляется в случае, если исходное значение тождественно false
. В противном случае класс не вставляется.
Так как invert
является противоположностью bool
, то в отсутсвии значения биндинга в разметку проставляется класс с именем определения. Класс также выставляется по умолчанию если атрибут default
имеет значение true
. При других значениях default
класс не выставляется.
<b:define name="foo" type="invert"/>
<div class="example {foo} prefix_{foo}"/>
Без установки значения биндингу:
<div class="example foo prefix_foo"></div>
foo == true
:
<div class="example"></div>
foo != true
:
<div class="example foo prefix_foo"></div>
Позволяет задать фиксированный список допустимых значений. Вставляет класс в том случае, если значение биндига входит в заданный список.
Список значений задается атрибутом values
, значения разделяются пробелом. Значения сравниваются оператором ==
и поэтому в списке возможно задать числовые значения.
Значение атрибута default
используется только в том случае, если такое значение определено в списке значений. В противном случае, или если атрибут не указан, по умолчанию класс вставлен не будет.
<b:define name="state" type="enum" values="processing ready error"/>
<b:define name="notReady" from="state" type="enum" values="processing"/>
<div class="prefix_{state} example_{notReady}"/>
Для state
будут приниматься только три значения и образовываться классы prefix_processing
, prefix_ready
и prefix_error
. При других значениях класс добавлен не будет. Для notReady
образуется единственный класс example_processing
, который будет вставлен только если state
(оригинальный биндинг) равен processing
Без установки значения биндингу:
<div></div>
state == 'ready'
:
<div class="prefix_ready"></div>
state == 'processing'
:
<div class="prefix_processing example_processing"></div>
Атрибут задает значение для используемого биндинга на момент создания экземпляра шаблона и до получения фактического значения биндинга. Это значение конвертируется в имя класса в соответсвии с правилами заданного типа.
Указание значения по умолчанию дает возможноть определить какие классы будут расставлены до применения значений биндингов. Это полезно для ситуаций, когда значение биндинга может не передаваться в шаблон.
Инструкция <b:define>
действует в рамках описания шаблона и не распространяется на включаемые шаблоны:
<b:define name="foo" type="bool"/>
<div class="{foo}">
<b:include src="./button.tmpl"/>
</div>
button.tmpl
<b:define name="foo" type="enum"/>
<button class="{foo}">
OK
</button>
Результирующая разметка (foo = 'scopes'
):
<div class="foo">
<button class="scopes">
OK
</button>
</div>
Как видно из примера, один и тот же биндинг имеет разные определения в разных шаблонах и, как следствие, образуются разные имена классов.
<b:define>
влияет только на те инструкции <b:include>
, что работают с атрибутом class
:
<b:set-class>
– задает биндинги с определениями из той области видимости, где определена сама инструкция<b:class>
и<b:append-class>
– добавляет биндинги с определениями из той области видимости, где определена сама инструкция; если у атрибутаclass
уже есть похожий биндинг, то он замещается<b:remove-class>
– удаляет указанные биндинги без учета того какие ограничения к ним применяются