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