Open lfoma opened 8 years ago
Можешь более подробно описать конкретную задачу из примера? Я не понимаю, что такое «отображается в виде тега» и при этом «является ссылкой». Скорее всего любую твою задачу можно решить существующими средствами, но чтобы мочь посоветовать правильное решение, нужно понимать задачу целиком.
Заодно можешь подкинуть еще примеров, где возникали проблемы.
Например, мне нужно реализовать вот такое меню: http://prntscr.com/bynzwg, т.е. элемент меню собирается из 2-х и более блоков, где каждый вносит какие-то изменения. Я сейчас решаю, вкладывая один блок контентом другого, но такое решение не всегда подходит и вообще противоречит изначальной структуре.
Чаще всего, проблема встречается, когда узел является блоком и элементом другого блока одновременно.
Напиши прямо BEMJSON, шаблоны и финальную разметку, которую нужно получить (тот вариант, который хочется).
В-общем то, набив немного шишек, пришел к правилу, что нельзя совмещать на одном узле блоки и элементы, содержащие шаблоны.
Если прям очень хочется, то это нужно делать уже в шаблоне того самого элемента.
Очень грубый и простой пример:
Хотим что бы элемент нашего меню был ссылкой, а при наведении, появлялось всплывающее окно. У нас уже есть блоки link
и popup
, которые мы хотим использовать.
Ожидаем, что верстка будет такая:
<li class="menu__item popup"><span class="popup__text">Привет, БЭМ!</span><a class="link" href="/here">Привет!</a></li>
Но это - неверный путь, который приведет к конфликтам шаблонов:
{
block: 'menu',
elem: 'item',
mix: [{block: 'popup', text: 'Привет, БЭМ!'}],
url: '/here',
content: [
{
block: 'link',
url: '/here'
content: 'Привет!'
}
]
}
//menu__item.bemhtml.js
block('menu').elem('item').tag()('li')
//popup.bemhtml.js
{
...
}
Но так не применятся шаблоны для popup
! Надо так:
{
block: 'menu',
elem: 'item',
popupText: 'Привет, БЭМ!',
url: '/here',
content: [
{
block: 'link',
url: '/here'
content: 'Привет!'
}
]
}
// menu__item.bemhtml.js
block('menu').elem('item')(
tag()('li'),
content()(
function() {
return [
{
block: 'popup',
text: this.ctx.popupText
content: applyNext()
}
];
}
)
)
//popup.bemhtml.js
{
...
}
Получится HTML:
<li class="menu__item"><div class="popup"><span class="popup__text">Привет, БЭМ!</span><a class="link" href="/here">Привет!</a></div></li>
Таким образом, можно применять бесконечное множество шаблонов, правильно выстраивая эту цепочку из зависимостей и вложенностей.
Я правильно познал дзен?
Собственно, уже не в первый раз возникает проблема, когда на одном узле нужно разместить несколько сущностей: несколько элементов, несколько блоков и т.д. Это абсолютно не противоречит концепции BEM и называется миксами. Но когда доходит дело до реализации, получается, что миксуемые сущности не отрабатывают свои шаблоны bemtree и bemhtml, а только добавляют свои классы. Считаю такое поведение шаблонизатором некорректным, т.к. каждый блок имеет право на самореализацию, даже если он - всего лишь миксин. Для примера, попробуйте скомпилировать это:
nav__item link popup tag
Это - элемент списка, который отображается в виде тега, является ссылкой, а при наведении, появляется тултип с подсказкой. Пример, конечно не ахти, но суть в том, что такая ситуация возникнуть может. Сейчас я это решаю, разнося сущности по разным узлам, увеличивая вложенность, но мне очень не нравится этот способ, т.к. является костылем, который можно не всегда применять, влияет на структуру документа.