Настоящим постом хочу продемонстрировать вам как будет выглядет API bem-xjst v8.x. Все пока на стадии RC, поэтому хочу выслушать ваше мнение по поводу всего этого.
Изменения, которые войдут в v8.x
- Все режимы теперь ведут себя одинаково: переопределяют значение из BEMJSON. (major)
- Добавлены недостающие режимы: mods() и elemMods() для установки модификаторов. (minor)
- Добавлены шорткаты режимов для добавления: addMix(), addAttrs(), addMods(), addElemMods(), addJs(). (minor)
- Добавлены шорткаты для добавления content: appendContent() и prependContent(). (minor)
TLDR; Песочница bem-xjst v8.x RC: https://goo.gl/ZeY4xL, в которой можно попробовать все эти вкусности…
Технические подробности
1. Все режимы теперь ведут себя одинаково: переопределяют значение из BEMJSON. (major)
Сейчас значение из шаблона режима content()
, bem()
, cls()
, tag()
переопределяет значение указанное в BEMJSON. Если вам нужно расширить значение из BEMJSON в шаблоне нужно использовать applyNext()
и this.extend()
/concat()
.
Однако режимы mix()
, js()
, attrs()
сейчас расширяют значение из BEMJSON.
Разное поведение режимов вносит некоторый раздрай и постоянно приходится держать в уме кто как себя ведет.
В v8.x мы привели все режимы к одинаковому явному поведению: переопределение значения из BEMJSON. Если вам нужно добавить что-либо, то теперь это можно будет сделать в явном виде — см п.3.
2. Добавлены недостающие режимы: mods()
и elemMods()
для установки модификаторов. (minor)
Под капотом эти режимы просто шорткаты к уже привычным всем конструкциям:
// mods()({something: myValue})
def()(function() {
this.mods = {something: myValue};
return applyNext();
});
и
// elemMods()({something: myValue})
def()(function() {
this.elemMods = {something: myValue};
return applyNext();
});
Как видно из примеров режимы mods()
и elemMods()
не имеют своей собственно очереди шаблонов, а добавляют шаблоны в стек к режиму def()
.
По умолчанию mods()
и elemMods()
возвратят вам значения из this.mods
и this.elemMods
соответственно.
Пример:
// BEMJSON
{ block: 'b' }
//Шаблоны
block('b').def()(function() {
return JSON.stringify(apply('mods'));
});
//Результатом будет:
[]
3. Добавлены шорткаты режимов для добавления: addMix(), addAttrs(), addMods(), addElemMods(), addJs().
Так как все режимы теперь переопределяют значение, то чтобы компенсировать необходимость писать applyNext()
для накапливания результата были введены шорткаты для уже существующих режимов add*()
.
Под капотом addJs()({ somekey: someval })
это
js()(function() {
return this.extend(applyNext(), { somekey: someval });
});
Под капотом addMix()({block: 'mixed' })
это
mix()(function() {
var res = applyNext();
if (!Array.isArray(res)) res = [ res ];
return res.push({block: 'mixed' })
})
Для остальных режимов аналогично.
Как видно из примера шорткаты add*()
не имеют своего стека шаблонов, а просто добавляют шаблон в стек соответствующего режима.
И, естественно, вы можете накапливать результат:
// Шаблоны
block('b')(
addJs()({ a: 1 })
addJs()({ b: 2 })
addJs()({ c: 3 })
);
// BEMJSON
{ block: 'b' }
// Результат:
<div class="b b_type_awesome i-bem" data-bem='{"b":{"a":1,"b":2,"c":3}}'></div>
4. Добавлены шорткаты для добавления content: appendContent() и prependContent().
// Шаблоны:
block('b')(
appendContent()(', templates!'),
appendContent()('!!1'),
prependContent()('(〜 ̄▽ ̄)〜 ')
);
// BEMJSON
{ block: 'b', content: 'Hello' }
// Результат:
<div class="b">(〜 ̄▽ ̄)〜 Hello, templates!!!1</div>
Как вы уже наверное догадались, это тоже шорткаты и они добавляют шаблоны в стек режима content()
. Пример:
// appendContent()(', templates!') это тоже самое что и:
content()(function() {
return [
applyNext(),
', templates!'
];
});
Классные изменения! Спасибо. Ждём релиз.
Много раз напарывался что в
BEMTREE
не отрабатывалjs()(true)
По поводуaddJs
раз это фактически extend, чтож не назвать тогдаextendJs
(но это уже чисто мое ИМХО) А так, релиз огонь!@JiLiZART а в BEMTREE и не должен отрабатывать
js()
. Там же всего 2 модыdef
иcontent
.Ещё replace
Т.е то что фактически выплевывает bemjson не может прописать js:true в исходном дереве? ну или js: {param: 1, param: 2}
@JiLiZART ничего не понял. Кто куда что выплевывает? В каком исходном дереве? Приведи пример, пожалуйста.
Ну банально я пробовал скажем внутри bemtree блока сделать элементу js параметры на основе данных
А мне addJs больше нравится. Меньше букв, лаконично.
@JiLiZART ну все правильно, нету у bemtree
js()
он и не вызывается