Skip to content

Latest commit

 

History

History
230 lines (146 loc) · 12.4 KB

b-define.md

File metadata and controls

230 lines (146 loc) · 12.4 KB

<b:define>

Инструкция используется для определения возможных значений биндинга в атрибуте 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 (опциональный) – значение по умолчанию

Другие атрибуты зависят от заданного типа.

name

Задает имя определения. Это имя должно быть валидным идентификатором и используется в качестве имени биндинга в разметке, но только для атрибута class. По сути инструкция переопределяет биндинг для атрибута class.

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

from

Атрибут позволяет задать имя биндинга, в случае если имя определения и биндинга не совпадают. В качестве значения используются только оригинальные биндинги передаваемые в шаблон. Определения объявленные с помощью <b:define> не учитываются.

Один из способ использования – переименование биндинга:

<b:define name="active" from="selected" type="bool"/>

<div class="{active}"/>

В данном примере, если selected == true у <div> будет класс active, иначе класса не будет.

type

Атрибут определяет тип значения и может принимать следующие значения:

  • bool – приведение значения к boolean
  • invert – инверсия значения
  • enum – фиксированный список значений

bool

Данный тип задает приведение значения биндинга к 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>

invert

Противоположность типу 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>

enum

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

Список значений задается атрибутом 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>

default

Атрибут задает значение для используемого биндинга на момент создания экземпляра шаблона и до получения фактического значения биндинга. Это значение конвертируется в имя класса в соответсвии с правилами заданного типа.

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

Область видимости

Инструкция <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> – удаляет указанные биндинги без учета того какие ограничения к ним применяются