Здравствуйте , у меня есть меню и там 10 списков li , как мне сделать так, чтобы я в бэм дереве его статически не описывал, а как то динамически вывести его. Хотя бы подсказку увидеть, в какую сторону мне двигаться чтобы этого добиться.
Здравствуйте , у меня есть меню и там 10 списков li , как мне сделать так, чтобы я в бэм дереве его статически не описывал, а как то динамически вывести его. Хотя бы подсказку увидеть, в какую сторону мне двигаться чтобы этого добиться.
@Rahnar что именно подразумевается под динамикой?
Ну , например из json дергать инфу , использовать его как некую такую базу данных. Либо как - то так, чтобы я не расписывал колбасу из 10 штук , написал один раз нужную вложенность, начиная с блока меню , соотвественно его элемент один li , который был бы описан динамически , а на выходе я получил уже собранное меню из 10 шт. Или вообще нет смысла от этих манипуляций ?? Как Вы друзья из Яндекс, описываете подобные вещи? Извините за идиотские вопросы , щас уровень наберу и все будет ок)
@Rahnar Похоже, все равно получается 3 варианта ответа :)
1. Чтобы «не писать колбасу».
BEMJSON — это JavaScript и можно смело пользоваться такими конструкциями:
Очевидно, что это по-прежнему будет статика, мы просто избавляемся от колбасы средствами JS прямо в статичном bemjson.js-файле.
2. Чтобы «написал один раз нужную вложенность».
Можно унести все в шаблон. bemjson.js:
bemhtml:
3. Пункт «чтобы из json дергать инфу» предполагает несколько очень разных вариантов решения:
3.1. Написать node.js-скрипт, который использовать вместо dev-сервера:
build.js
Это, конечно, неудобно. Код я привел, чтобы было понятно, что там происходит под капотом.
3.2. В ветке
bem-tools
есть коммит про поддержкуrequire
прямо в bemjson.js-файлах.Можно склонировать ее в node_modules, сказать там
npm link
и пользоватьсяbem server
для сборки. Это уже удобнее, но придется пользоваться пока еще невыпущенной версией сборщика.3.3. Настроить сборку так, как описано в документе «Шаблонизация данных в bem-core».
Если коротко, то схема предполагает 2 этапа шаблонизации:
Пример готовой настройки для ENB можно взять тут https://github.com/tadatuta/bem-bemtree-static-project-stub Отличия от официального
project-stub
видны в этом коммите:Важное отличие от подхода из
project-stub
: теперь декларацией для сборки служит неbemjson.js
, аbemdecl.js
, т.к.bemjson.js
генерируется на основе BEMTREE-шаблонов динамически в процессе сборки. В данном конкретном случае точкой входа служит блокroot
. Все остальные блоки попадают в сборку по зависимостям.В результате это по-прежнему статическая генерация HTML, но уже двухпроходная, что избавляет от написания колбасы руками.
4. Полноценное динамическое приложение
Здесь работает тот же принцип двухпроходности, но вместо того, чтобы описывать каждую страницу заранее, используется сервер, который будет отдавать разные данные в зависимости от урла и прочих пользовательских настроек.
Я обязательно напишу про этот пункт отдельный подробный пост и сделаю демо-репозиторий. А пока рекомендую посмотреть https://github.com/bem/sssr и сопровождающее видео с BEMUp-а.
@tadatuta сейчас возникла таже необходимость :)
Из перечисленного делаю 2-ым способом, но больше всех нравится 3.2 (т.к. для 2-го варианта необходимо "чистить" входные данные, чтобы визуально они не засоряли bemjson)
Ого!!Спасибо огромное , Владимир! Очень все доходчиво! И вот такой вопрос еще, начал изучать фреймверк i-bem.js , все никак не пойму, он полностью заменяет нативный javascript, тобишь мы пишем на нем используя ваш синтаксис и ООП. Он позволяет решать небольшие задачи , типа слайдер написать? И можно ли обходиться без него?Хотя , я намерен его использовать ,просто хочу понять диапазон его применения.Или на нем можно сделать все то, что можно сделать на жуке(jquery)?
@tadatuta а можно использовать переменные? Допустим у меня данные дублируются, но используются в разных блоках по разному. Как это будет выглядить в bemjson?
@Rahnar i-bem.js - это вполне себе нативный js. Да, он позволяет решать небольшие задачи, "типа слайдер написать". Вот вам пример карусели. Под капотом у i-bem jquery, так что да, на нем можно сделать все то, что можно сделать на jquery.
@Rahnar Хорошими примерами компонентов на i-bem.js могут служить блоки из bem-components.
По поводу i-bem.js и jQuery: у i-bem-блоков есть поле
domElem
, которое является указателем на jQuery-chain данного блока. Т.е. this.domElem в i-bem-блокеbutton
— это то же самое, что$('.button').eq(0)
. Кроме того все элементы представлены jquery-коллекциями (this.elem('control') == $('.button__control')
).Можно сказать, что i-bem.js добавляет к jQuery возможность декларативно описывать компоненты и предоставляет хелперы для работы с предметной областью БЭМ (проверить, установить или поменять модификаторы, найти элементы и т.п.).
@belozyorcev
Вот прямо совсем как в любом JS-файле ;) Ну, например,
@tadatuta это именно в bemjson ? Или в шаблонах? В bemhtml я свободно пользуюсь, а вот задать где-то глобально в bemjson не пойму как
@belozyorcev В bemjson. Можно вот прямо так целиком скопировать сниппет, который я привел выше, он будет работать ;)
bemjson.js-файл
вproject-stub
просто эвалится в пустом контексте (vm.runInNewContext()
) и результат отдается вBEMHTML.apply()
. Т.е. важно, чтобы в результате выполнения bemjson.js вернулась строка или js-объект, а внутри может быть произвольный JS-код.PS: ENB для выполнения bemjson.js-файлов использует метод
requireOrEval
, что означает, что в bemjson-файлах можно использоватьrequire
уже сейчас, если экспортировать их как common.js-модули:index.bemjson.js:
Я тоже сейчас пилю двухуровневое меню на базе bem-components. Надеюсь через неделю выложить на общий суд и собрать фидбек.
По-моему, самый простой и верный способ собирать такое меню в bemtree шаблоне. Выглядеть будет примерно так:
@tadatuta - а путь
require('./data.json')
относительно чего строится?@tadatuta. С путём разобрался :) Относительно bemjson файла.
Вот другая задача. Делаю следующее
но получаю при перезагрузке браузера
undefined
. Пока не знаю куда копать...в list я должен получить массив элементов, которые затем обработать в bemtree/bemhtml
@belozyorcev Если я правильно угадываю, чего хочется добиться, то должно быть как-то так:
@tadatuta я не понимаю, куда это вставлять в bemjson файле? У нас же оно построенно как объект JS. Но тут у нас появляется переменная bemjson. У меня начинает путаница возникать в голове...
П.Н. Что делает это код понимаю, а вот как использовать этот код в bemjson файле нет.
@belozyorcev bemjson.js — это просто javascript-файл. все, что требуется — это чтобы в результате его выполнения экспортировалось дерево. а код может быть совершенно произвольным. поэтому то, что я привел выше — это и есть контент bemjson.js-файла. если начинать от
page
, то он может выгядеть, допустим, так:@tadatuta теперь в моей голове всё прояснилось и стало на свои места :) Спасибо, всё заработало :) Теперь bemjson файл похудеет раза в 3-4
После перевода на
require
подход - размер bemjson уменьшился в 5 раз. Стало быстрее и проще ориентироваться в "чертеже" проектаДелаю сейчас меню по такому принципу:
bemjson:
в бемхтмл кладу
выдает ошибку Cannot read property '0' of undefined а если засунть мой массив с title и url в сам bemhtml и сделать на него map, то он увидит содержимое массива...
Блок
menu
изbem-components
поддерживает толькоmenu-item
илиmenu__group
в свойствахcontent
@Guria тобишь так
Почти.
menu-item
это отдельный блок: https://ru.bem.info/libs/bem-components/v2.0.0/desktop/menu-item/ PS. код можно оформлять с помощью github-flawored markdownВот пример из моей реализации меню: https://github.com/Guria/bem-drawer-menu/blob/master/common.blocks/kg-menu/__items/_type/kg-menu__items_type_main.bh.js#L10-L32
@Guria а почему может не работать блок link я обернул в нее блок image и он как тэг определился сам , а вот блок линк не хочет((
@Rahnar продемонстрируй код
@Rahnar Предположу, что не хватает зависимостей в deps.js
как правильно код вставить , красивый ? Я оборачиваю в тег
<code>
чет не получается..@tadatuta Вы правы Владимир, написал deps и все прекрасно увидел.
Три бек-тика (`) и опционально слитно язык (например, js) в начале и просто три бек-тика в конце.