bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Как создать блок в runtime #46

Open ghost opened 10 years ago

ghost commented 10 years ago

Подскажите как создать блок BEM (в идеале из BEMJSON) в runtime, например по событию нажатия на кнопку, и добавить его в к содержимому другого блока.

tavriaforever commented 10 years ago

Привет. Ответ на твой вопрос тут http://ru.bem.info/technology/i-bem/2.3.0/i-bem-js/#Динамическое-обновление-блоков-и-элементов-в-DOM-дереве

Если останутся вопросы, спрашивай.

ghost commented 10 years ago

Привет. Спасибо большое за инфу. Добавлю, на случай, если у кого еще возникнет такой вопрос, что у меня выполнение BEMHTML.apply({BEMJSON}) отваливалось с ошибкой Match failed, причина была в том, что не подключил я файл index.bemhtml.js.

tadatuta commented 10 years ago

@atott Чуть-чуть добавлю по этому поводу. Дело в том, что в *.bemhtml.js попадает код всех шаблонов, например, блока page, которые, скорее всего, реально не используются на клиенте. Поэтому более эффективный способ — это использование depsByTech. Они позволяют выразить зависимости вида «клиентский JS моего блока A, требует для своей работы BEMHTML-шаблоны блоков B, C и D». Например:

[
{
    tech: 'js',
    shouldDeps: [
        { block: 'i-bem', tech: 'bemhtml' }, // нужен всегда, содержит базовые шаблоны
        { block: 'B', tech: 'bemhtml' },
        { block: 'C', tech: 'bemhtml' },
        { block: 'D', tech: 'bemhtml' }
    ]
},
{
    shouldDeps: [/* тут обычные зависимости блока */]
}
]

в результате только нужные шаблоны соберутся прямо в _index.js и подключать index.bemhtml.js не потребуется.

ghost commented 10 years ago

@tadatuta только сегодня дошли руки посмотреть, да, это работает четко. Спасибо большое!

mursya commented 10 years ago

если вы хотите задать вопрос команде, то ставьте еще и метку asktheteam ;) спасибо!

maxt commented 10 years ago

Пример из документации посмотрел. Но ведь там лишь BEMHTML сформирует HTML по заданному BEMJSON. А что если нужно на страницу в рантайме добавить блок, содержащий реализации в технологии js ну и плюс css? В документации указано, что "Все функции автоматически выполняют инициализацию блоков на обновленном фрагменте DOM-дерева." (речь о js inited?) Но как и когда будет загружена реализация блока в технологии js?

tadatuta commented 10 years ago

@maxt Есть 2 подхода:

  1. Чаще всего разработчик заранее знает, какие блоки потенциально могут потребоваться и заранее добавляет их в сборку с помощью deps.js, а в рантайме генерируется только BEMJSON, из которого строится HTML.
  2. Если блок, который может появиться динамически, реально используется очень редко, а его CSS- и JS-реализация слишком тяжелые, то можно собрать бандл, который загрузить с помощью AJAX-запроса.
maxt commented 10 years ago

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

tadatuta commented 10 years ago

самое простое — написать такой bemdecl, который будет включить только зависимости этого тяжелого блока, собрать по этой декларации deps, вычесть из полученного deps-файла зависимости основного бандла и по тому, что останется, собрать CSS и JS, а далее в рантайме по наступлению некоего события вставить их в DOM в виде тегов link и script.

есть более хитрый вариант с объединением CSS и JS в один файл, чтобы получить их за один запрос, но пока инструменты для автоматизации этого сценария мы не довели до состояния, когда не стыдно в opensource.

maxt commented 10 years ago

@tadatuta спасибо большое за объяснение, идея ясна.