Войти с помощью github

Возможно ли спроектировать i-bem блок (без DOM представления) так, чтобы при первом вызове BEM.create('block') создался блок, при последующих отдавался уже инстанс этого блока?

По ходу своей работы, часто сталкиваюсь с ajax запросами внутри i-bem блоков. Часто повторяющиеся паттерны решил вынести в отдельную надстройку над jquery.ajax.

Где можно использовать?

Допустим у вас есть кнопка, которая по клику на себя, добавляет куда то контент, а когда контента нет, удаляет сама себя

_onButtonClick: function () {
    Http
        .abortable(this)
        .get(this.params.url)
        .then(function (response) {
            BEMDOM.replace(this.domElem, response.getText());
        }.bind(this));
}

Eсли вдруг по кнопке нажали два раза, предыдущий запрос отмениться, так же навешаются правильные обработчики, которые, в случае удаления блока, остановят запрос и удалят все ненужные ссылки.

Или по клику на ссылку вам нужно подгрузить текст для модального окна, закешировать его, и при последующих кликах отдавать данные из кеша.

_onButtonClick: function () {
    Http
        .once(this)
        .get(this.params.url)
        .then(function (response) {
            this.showModal(response.getText());
        }.bind(this));
}

запрос на сервер отработает только единожды, последущие вызовы, этой функции, запросы на сервер делать не будут, просто буду возвращать отработанный промис.

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


this._req = Http.abortable(this);

this._req.get(this.params.someUrl).then(this._onSomeDone); //этот запрос отменится, т.к следом идет другой
this._req.get(this.params.anotherUrl).then(this._onAnotherDone);

Не нужно плодить дополнительных переменных, самому вызывать abort() у jqXHR перед другим запросом.

Или если нужно сделать два разных запроса в разные места

Http.abortable(this, 'some').get(this.params.someUrl).then(this._onSomeDone);
Http.abortable(this, 'another').get(this.params.anotherUrl).then(this._onAnotherDone);

https://github.com/JiLiZART/bem-http

Ставим через bower install bem-http, и подключаем в уровнях { path: 'libs/bem-http/common.blocks', check: false }.

Пример как использовать в блоке https://github.com/JiLiZART/bem-http/blob/master/example.blocks/app/app.js

P.S. Если есть какие либо идеи по улучшению API, буду очень благодарен.

Где-то попадалась статья (или пост), не могу сейчас найти.

Задача: "подмешать" к основному блоку функционал другого.

В простейшем варианте (то, что заработало) получается во время инициализации первого сказать примерно так:

var second_block_object = this.domElem.bem('second_block');

-- тогда имею почти то, что нужно: объект второго блока, ассоциированный с dom-узлом.

Но хотелось бы уметь указывать необходимость примеси из шаблонов и оттуда же передавать параметры второму блоку (js()({ ... })). К сожалению, через mix таким образом подцепить нужный блок не удаётся. Как это делается правильно? (Как-то ведь делается?.. Вроде бы видел даже примеры...)

Есть желание реализовать автосохранение текущего состояния SPA интерфейса в центральном хранилище, возможность передать его как JSON, как URL и загрузить обратно из JSON/URL.

Т. е. у части блоков имеется не-BEM имя ~ как имя инпута HTML-формы. Как правильно по BEM реализовать такой глобальный функционал? Как лучше хранить данные типа input type=hidden, не имеющие своих блоков?

Есть утилиты которые атомарно изменяют DOM не используя virtual DOM. Есть мысль прикрутить morphdom к i-bem.js. Однако, есть сомнения что затея сработает. Например, непонятно что будет с событиями, будут ли инициализироваться блоки. Кто в теме подскажете в какую сторону копать?

Пытаюсь перевести проект на полный бем-стек. Пытаюсь сделать блок выбора параметров товара ( например, размера ). Есть блок .params, внутри него лежат элементы ( собственно размеры ) .params__item. Делаю ленивую инициализацию по клику на эелемент .params__item. При клике хочу назначить элементу на котором кликнули модификатор _selected.

Пытаюсь это сделать через this.setMod(this.elem('item'), 'selected') но в таком случае модификатор устанавливается всем элементам. Как их фильтровать?

Как вообще работать с домом внутри блока? Допустимо ли извлекать данные из event, например event.target? Где граница ипосльзования фрейморка и работа с чистым js?

Делаю тривиальную вещь:

this.toggleMod('child', params.childIdx);

childIdx — число. Мод ставится на блок, но при повторном вызове хендлера не убивается. Числа начинаются с единицы.

Если сделать так, то всё работает ожидаемо:

this.toggleMod('child', 'num-' + params.childIdx);

Собственно, уже не в первый раз возникает проблема, когда на одном узле нужно разместить несколько сущностей: несколько элементов, несколько блоков и т.д. Это абсолютно не противоречит концепции BEM и называется миксами. Но когда доходит дело до реализации, получается, что миксуемые сущности не отрабатывают свои шаблоны bemtree и bemhtml, а только добавляют свои классы. Считаю такое поведение шаблонизатором некорректным, т.к. каждый блок имеет право на самореализацию, даже если он - всего лишь миксин. Для примера, попробуйте скомпилировать это: nav__item link popup tag Это - элемент списка, который отображается в виде тега, является ссылкой, а при наведении, появляется тултип с подсказкой. Пример, конечно не ахти, но суть в том, что такая ситуация возникнуть может. Сейчас я это решаю, разнося сущности по разным узлам, увеличивая вложенность, но мне очень не нравится этот способ, т.к. является костылем, который можно не всегда применять, влияет на структуру документа.

Вопрос №1

modules.define('page',
  ['i-bem-dom'],
  function (provide, bemDom) {
    provide(bemDom.declBlock(this.name, {
      onSetMod: {
        'js': {
          'inited': function () {
            // this.findChildBlock(FormLogin)._events().on('login:success', this._onLoginSuccess)
          }
        }
      }
  }))
})

// modules.require('page', function () {})

инициализация происходит только если раскомментировать последнюю строчку. Это нормально или я что-то не так сделал?

Вопрос №2.

Блок page я планирую использовать как глобального диспетчера. У page есть разные view (со своими наборами слушателей). По сути будет 3 view. (login, user, admin),

При переходе из view в другой view нужно менять вешать/убирать слушателей. Как это реализовать?

Пока начал эксперементировать с модификаторами. Но такой код срабатывает только при инициализации.

modules.define('page',
  ['form-login'],
  function (provide, FormLogin, Page) {
    Page.declMod({ modName: 'view', modVal: 'login' }, {
      onSetMod: {
        'js': {
          'inited': function () {
            console.log('login view')
            // console.log(this.findChildBlock(FormLogin))
            this.findChildBlock(FormLogin)._events().on('login:success', this._onLoginSuccess)
          }
        }
      },

      _onLoginSuccess: function (e, data) {
        console.log(data)
      }
    })

    provide(Page)
  }
)

Вопрос №3

Какая разница между

provide(bemDom.declBlock())

и

bemDom.declBlock()
provide(bemDom)

Всем доброго дня.

Пытаюсь подписаться на делегированное БЭМ-событие с пересечением границы блока.

Есть структура:

страница
  панель
    ссылки

Если я в js: inited панели подписываюсь

NotesLink.on(this.domElem, "click", this._onLinkClicked, this);

то события приходят, а если - в js: inited страницы, то - нет.

Пытался в качестве первого параметра подавать domElem панели - события всё равно не приходят.

Что наводит на мысль, что БЭМ-события не пересекают границ блока, содержащего блоки, генерирующие события. Это так?

Доброго дня.

Не могу разобраться, как правильно заменять содержимое блока, чтобы дочерние блоки были автоматически инициализированы.

Есть панель со ссылками, которые являются блоками. По событию содержимое панели нужно обновить новыми ссылками. Код выглядит так:

var html = // ручной рендеринг
BEMDOM.update(this.domElem, html);

В документации (https://ru.bem.info/technology/i-bem/v2/i-bem-js-init/#init-ajax) написано, что BEMDOM.update выполняет динамическую инициализацию блоков, но для моих ссылок этого не происходит, и приходится писать вот такой код инициализации:

$(".notes-link", this.domElem).each(function(_, link) {
    $(link).bem("notes-link");
});

Я подозреваю, что блоки для автоматической инициализации нужно обложить какими-нибудь специальными атрибутами. Пробовал оформлять ссылки так: <a href="#" class="notes-link i-bem" data-bem="{&quot;notes-link&quot;: {}}">link text</a>

Но не помогло.

Может кто-нибудь подсказать, как правильно инициализировать новодобавленный контент?

Насколько я помню ymodules не умеет подключать модули из внешних файлов. А очень надо. Если модуля нет в рантайме, то подгружать его по url, как в requirejs. Возможно ли это? Если да, то в какую сторону смотреть?

Всем привет!

Сегодня мы зарелизили bem-core@v4.0.0-rc.1.

Это релиз-кандидат большого релиза bem-core@v4.0.0, который появится совсем скоро.

Мы сделали достаточно большое количество обратно несовместимых изменений, ради того, чтобы API стало легче понять, запомнить и удобнее использовать.

Уже доступен миграционный гайд и обновлённая документация на i-bem.js. Если вы не используете bem-components, то можно начинать изучать, крутить, вертеть и подключать к своим проектам новую версию bem-core.

Что нового и важного:

  • Значительно упрощено и унифицировано API работы со всеми видами событий:

    this._domEvents().on('click', this._onClick);
    this._events(this.findChildBlock('button')).on('click', this._onButtonClick);
    

    Кроме того, теперь все основные способы использования не требуют самостоятельного удаления подписок при уничтожении экземпляра — отписка происходит автоматически. Подробнее в миграционном гайде.

  • Экземпляры для элементов перенесены в блоки i-bem и i-bem-dom и стали частью ядра. Теперь с элементами работать так же удобно, как с блоками:
this.findChildElem('button').setMod('disabled');

Подробнее в миграционном гайде.

  • Функциональность элемента collection блока i-bem перестала быть опциональной. Все методы, возвращавшие несколько БЭМ-сущностей, теперь возвращают коллекции:

    this.findChildBlocks('control').setMod('disabled');
    

    Подробнее в миграционном гайде.

  • Ленивая инициализация (поле live) разделена на две отдельные части — поле lazyInit и метод onInit(). Более явные названия без смешивания в одном месте двух вещей. Подробнее в миграционном гайде.
  • Удалены и переименованы множество методов — API стало чище и понятнее.

Все подробности о миграции на новую версию читайте в миграционном гайде. А документация на i-bem.js уже содержит полностью обновлённую информацию.

Мы просим вас писать нам любой фидбек о найденных ошибках и проблемах на форум или сразу в тикеты, чтобы мы могли сделать обратно несовместимые исправления до полного релиза bem-core@v4.0.0.

P. S. Релиз-кандидат bem-components с bem-core@v4 внутри будет в ближайшее время. Также мы ещё допишем английскую версию документации, чейнджлог и миграционный гайд.

Предусмотреть конфигурацию i-bem в режиме отладки, в котором в момент подписки this.on в аттрибуты соответствующего html-элемента будет записываться название метода и его блока ИЛИ записывать в некое хранилище ссылку на метод-обработчик, с некоторым уникальным ключом, и ключ этот добавлять опять же к html-элементу (что-то типа: data-event-debug-id).

Благодаря этому станет легче дебажить, а можно ещё и плагин накрутить.

Или всё и так просто, а я не в курсе?

Проблема такая: есть кнопка, но пока в коде найдёшь для неё обработчик потратишь уйму времени.

Всем привет.

Наткнулся на реализации Flux для BEM. Сразу всплыла мысль про events__channels. Какой профит от использования Flux, если мы можем через каналы кидать события + данные?

Возможно я не очень сильно понимаю идею хранилищ.

Имеется блок chart с элементом legend. как можно вызвать методы элемента в ymodule? Каждая диаграмма содержит элементы(заголовок, легенда,график и тд) Хочу создать блок для диаграмм у которого в роле элементов выступают как раз элементы(заголовок, легенда,график и тд) В элементе легенды хочу сделать статический метод что то вроде js render() а из блока chart вызывать его. может где то я не прав в методолгоии и нужно реализовывать легенду отдельным блоком?

chart.js

modules.define('chart', ['i-bem__dom','d3','BEMHTML'], function (provide, BEMDOM, D3, BEMHTML) {
    provide(BEMDOM.decl(this.name, {
        onSetMod: {
            js: {
                inited: function () {
                    this._graphic = this.findElem('graphic');           //Находим елемент графика
                    this._legend = this._elem('legend');                //Находим елемент легенды
                    this._cdata = this.params.data;                     //предварительная обработка входящих данных
                                        this._legend.someMethod() // Ругается что не существует метод
                }
            }
        }
    }));
});

legend/chartlegend.js

modules.define('chart', ['i-bem__dom','d3'], function(provide, BEMDOM, D3) {
provide(BEMDOM.decl(this.name, {
    onSetMod: {
        js: {
            inited: function(){
        this.__base.apply(this, arguments);     // тут не понятно немножко момент № 1
                console.log("chart_legend inited");
            }
        }
    },
    someMethod: function() {
             console.log("chart_legend generate");
                 return "911";
    },

}));
});

обязательно js-модуль дефайнить как блок? если так делать то модель элемента поавторитетней модуля блока, поэтому нужно this.__base.apply() вызывать?!

И немножко не по теме, почему то в таком контексте(chart.js) не срабатывает js BEMHTML.apply({block:'someblock',content:'someContent'}); - ничего не возвращает.

Делаю форму как в примере SSSR. Есть несколько полей (блоки input). Если использовать findBlockInside(), то он находит только первый инпут. Мне нужно чтобы все поля были обязательными. Что делать?

Есть ли в i-bem собственный способ получать и отправлять данные (GET/POST) на сервер в json? Например для отправки данных с формы на сервер? Серверная часть написана на PHP (Laravel 5). Общается с фронтендом через API посредством get и post запросов. До этого использовали Vue JS, в нем была возможность общения с сервером из компонента. Интересует тоже самое только через i-bem

Подскажите был ли в bem-bl метод destruct() у блока? Заинтересовал вот этот код. Под bem-core он работать отказывается. Я заменил на BEMDOM.destruct() но вопрос, правильно ли?

Наверное все кто используют IDE, а не emacs сталкивались с проблемой, что IDE совсем не понимает BEM блоки. Это все связано с особенностями реализации наследования внутри bem-core - inherit.

При помощи JSDoc я всячески стараюсь объяснить IDE что же такое BEM-block. Но, увы 100% результат пока не достиг, имеются недостатки. Вот пример того как я описываю блоки:

/**
 * @module myBlock
 */
modules.define('myBlock', ['i-bem__dom'], function(provide, BEMDOM) {

/**
 * @augments BEM
 * @bem
 */
var myBlock = BEMDOM.decl(this.name, /** @lends myBlock.prototype */ {
    onSetMod: {
        js: {
            /**
             * @constructs
             */
            inited: function() { /* some code goes here */ }
        }
    }
}, /** @lends myBlock */ {
    live: function() {
        this.liveBindTo('some-elem', 'click', this.prototype._onSomeElemClick);
    }
});

provide(myBlock);

});

Подробнее:

  • имена классов и модулей не должны содержать тире, хоть BEM и предлагает нам называть блоки через тире, то JSDoc в именах классов тире не понимает, и напроч забивает на весь последующий код.
  • результат выполнения BEMDOM.decl надо класть в переменную, если сразу положить в provide работать не будет.

В целом данная схема оформления позволяет комфортно работать с прототипной частью блока, что касается live, там я пока не нашел решения.

Я не нашел никакого способа объяснить IDE, что эта часть наследуется от BEMDOM и BEM одновременно, но только от их статической части. Кажется к такому JSDoc не готов. В связи с чем у меня IDE не понимает что this.prototype, это прототип нашего же блока.

Сам я недавно стал заморачиваться с JSDoc и еще многого про него не знаю. Если у вас есть идеи как усовершенствовать описание блоков буду рад любой информации/критике

Делаю вроде простую вещь, но "что-то идет не так".

Хочу, чтобы при нажатии на кнопку "Добавить ещё один адрес" через bemhtml вставлялся такой же блок .address-wrap. Он вставляется, но не понимаю, как сделать так, чтобы на кнопке вновь созданного блока висело событие на создание очередного.

Ниже примеры кода для bemjson, js, deps

часть bemjson

                                      {
                                            block: 'address-wrap',
                                            js: true,
                                            content: [
                                                {
                                                    block: 'content',
                                                    elem: 'title',
                                                    elemMods: { size: 'xs', countable: true },
                                                    count: '3.',
                                                    content: 'Укажите адрес вашего офиса'
                                                },
                                                {
                                                    block: 'form-item-v2',
                                                    mix: { block: 'row' },
                                                    content: [
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form',
                                                                elem: 'label',
                                                                content: 'Город'
                                                            }
                                                        },
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form-input',
                                                            }
                                                        }
                                                    ]
                                                },
                                                {
                                                    block: 'form-item-v2',
                                                    mods: { unerrored: true },
                                                    mix: { block: 'row' },
                                                    content: [
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form',
                                                                elem: 'label',
                                                                content: 'Улица'
                                                            }
                                                        },
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form-input',
                                                            }
                                                        }
                                                    ]
                                                },
                                                {
                                                    block: 'form-item-v2',
                                                    mods: { unerrored: true },
                                                    mix: { block: 'row' },
                                                    content: [
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form',
                                                                elem: 'label',
                                                                content: 'Дом/Корпус'
                                                            }
                                                        },
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form-input',
                                                            }
                                                        }
                                                    ]
                                                },
                                                {
                                                    block: 'form-item-v2',
                                                    mods: { unerrored: true },
                                                    mix: { block: 'row' },
                                                    content: [
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form',
                                                                elem: 'label',
                                                                content: 'Офис'
                                                            }
                                                        },
                                                        {
                                                            block: 'col-md-4',
                                                            content: {
                                                                block: 'form-input',
                                                            }
                                                        }
                                                    ]
                                                },
                                                {
                                                    block: 'form-item-v2',
                                                    mods: { unerrored: true },
                                                    mix: { block: 'row' },
                                                    content: [
                                                        {
                                                            block: 'col-md-4',
                                                            mix: { block: 'col-md-offset-4' },
                                                            content: {
                                                                block: 'btn',
                                                                mods: { size: 'm', 'full-width': true, color: 'green-transparent' },
                                                                mix: { block: 'address-wrap', elem: 'btnAdd' },
                                                                content: 'Добавить ещё один адрес'
                                                            }
                                                        }
                                                    ]
                                                }
                                            ]
                                        },

address-wrap.js

modules.define('address-wrap', ['i-bem__dom', 'BEMHTML', 'jquery'], function(provide, BEMDOM, BEMHTML, $){
    provide(BEMDOM.decl(this.name,
        {
            /* Instance methods */
            onSetMod: {
                'js': {
                    'inited': function() {
                        var that = this;
                        this.counter = 0;

                        this.bindTo('btnAdd', 'click', function (e) {

                            var bemJSON = {
                                block: 'address-wrap',
                                js: true,
                                content: [
                                    {
                                        block: 'content',
                                        elem: 'title',
                                        elemMods: { size: 'xxs'},
                                        mix: { block: 'offset', mods: { 'margin-top': 'reset' } },
                                        content: 'Укажите дополнительный адрес вашего офиса'
                                    },
                                    {
                                        block: 'form-item-v2',
                                        mix: { block: 'row' },
                                        content: [
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form',
                                                    elem: 'label',
                                                    content: 'Город'
                                                }
                                            },
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form-input'
                                                }
                                            }
                                        ]
                                    },
                                    {
                                        block: 'form-item-v2',
                                        mods: { unerrored: true },
                                        mix: { block: 'row' },
                                        content: [
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form',
                                                    elem: 'label',
                                                    content: 'Улица'
                                                }
                                            },
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form-input'
                                                }
                                            }
                                        ]
                                    },
                                    {
                                        block: 'form-item-v2',
                                        mods: { unerrored: true },
                                        mix: { block: 'row' },
                                        content: [
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form',
                                                    elem: 'label',
                                                    content: 'Дом/Корпус'
                                                }
                                            },
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form-input'
                                                }
                                            }
                                        ]
                                    },
                                    {
                                        block: 'form-item-v2',
                                        mods: { unerrored: true },
                                        mix: { block: 'row' },
                                        content: [
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form',
                                                    elem: 'label',
                                                    content: 'Офис'
                                                }
                                            },
                                            {
                                                block: 'col-md-4',
                                                content: {
                                                    block: 'form-input'
                                                }
                                            }
                                        ]
                                    },
                                    {
                                        block: 'form-item-v2',
                                        mods: { unerrored: true },
                                        mix: { block: 'row' },
                                        content: [
                                            {
                                                block: 'col-md-4',
                                                mix: { block: 'col-md-offset-4' },
                                                content: {
                                                    block: 'btn',
                                                    mods: { size: 'm', 'full-width': true, color: 'green-transparent' },
                                                    content: 'Добавить ещё один адрес'
                                                }
                                            }
                                        ]
                                    }
                                ]
                            };

                            that.createAndBind(bemJSON);

                        });
                    }
                }
            },

            addAdress: function(){
                var that = this;
                console.log('add address');
                that.counter++;
            },

            delAddress: function(){
                var that = this;
                console.log('del address');
                that.counter--;
            },

            createAndBind: function(bemJSON){
                var that = this;
                BEMDOM.after(that.domElem[0], BEMHTML.apply(bemJSON));
            }
        },
        {
            /* Statics methods */
        }));
});

address-wrap.deps.js

([
    {
        mustDeps: 'i-bem',
        shouldDeps: [
            { elem: 'jquery' }
        ]
    },
    {
        tech: 'js',
        mustDeps   : [
            {
                block: 'address-wrap',
                tech: 'bemhtml'
            }
        ]
    }
])

А как сейчас с поддержкой модификаторов без значений в i-bem, bem-xjst?

Судя по этой странице: https://ru.bem.info/technology/i-bem/v2/i-bem-js-mods/#mods-api i-bem, например, уже поддерживает. Только в bem-core?

Хочу доопределить инициализацию блока dropdown.

Нужно что бы он инициализировался когда инициализируется блок на котором он примиксован. Как мы знаем у dropdown свитчер блок рисуется в зависимости от его модификатора. А ещё в моду switcher можно засунуть любой другой блок и он все равно на него замиксуется.

Как правильно решить задачу: Инициализируем dropdown когда блок в моде switcher заинициализировался (*_js_inited) ну или по ховеру на контролле (*_hovered).

хочется (но не можется) в live для dropdown написать что-то типа такого:

this.liveInitOnBlockEvent(
    { modName: 'js', modVal: 'inited' }, 
    this.getMod('switcher') // или любая другая функция которая вернет тот самый правильный блок
);

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

В общем подскажите. Завязываться на dom событие в этом случае кажется нифига не круто.

Добрый день, используем в проекте фреймворк bnsf автора @apsavin Вопрос скорее всего к автору: как создавать публичные параметры приложения. Раньше не работал с yml. Методом научного тыка создал файл index.parameters.dist.yml и из него получаю нужные переменные в роутинге. Публичные параметры, как я понял, складываются в data-parameters блоку page, но не могу понять как их создавать. Хотелось бы больше информации по этому поводу.

Ситуация следующая, есть код:

    onElemSetMod: {
        'formating': {
            'type': {
                '1': function (elem, modName, modVal, prevModVal) {
                    console.log(BEMHTML.apply({block : 'input',val : 'bla'}));
                    console.log(BEMHTML.apply);
                    BEMDOM.update(elem,
                        '<div></div>'
                    )
                },
                '2': function (elem, modName, modVal, prevModVal) {
                    console.log(1)
                }
            }
        }
    }
}))

});

в котором BEMHTML.apply выдает мне пустую строку. Проверив весь свой код, случайно обнаружил следующую строку в файле \node_modules\enb-bemxjst\techs\bemhtml.js:

var code = 'exports.apply = function () { return ""; };',

Не могли бы Вы помочь разрешить эту проблему.

Привет, ребят! Никто не сталкивался с такой задачей: есть landing page состоящий из 5 блоков (height:100%, width:100%). Нужно трегирить события для каждого блока при его появлении, чтобы управлять анимацией (появился блок при скролле, плавно появился заголовок, при исчезновении - пропал, и т.д.). Подскажите, как это лучше реализовать (для каждого блока писать свой i-bem.js код или привязать все к общему блоку) , может кто-то уже делал подобное, ведь анимация сейчас в моде. Просьба сторонние библиотеки не предлаагать, только i-bem.js.

Здравствуйте, я новичок в BEM. Помогите разобраться, пожалуйста.

Я подключил bem-components в проект dist-способом

<link rel="stylesheet" href="https://yastatic.net/bem-components/2.4.0/desktop/bem-components.css">
<script src="https://yastatic.net/bem-components/2.4.0/desktop/bem-components.js+bemhtml.js"></script>

Также у меня есть форма с несколькими select-блоками из bem-components, html которых скопировал со странички описания:

<form class='filter-form i-bem' data-bem='{ "filter-form": {} }'>
    <div class="select select_mode_radio select_theme_islands select_size_m i-bem" data-bem='{"select":{"name":"city"}}'>
        ...
    </div>
    <div class="select select_mode_radio select_theme_islands select_size_m i-bem" data-bem='{"select":{"name":"region"}}'>
        ...
    </div>
</form>

Мне нужно при изменении значения определенного select, а именно city, выполнить некоторые действия (если интересно, то нужно сделать post-ajax и выполнить submit формы).

Вроде надо что-то типа этого:

modules.define('filter-form', ['i-bem__dom'], function(provide, BEMDOM) {
    provide(BEMDOM.decl(this.name, {
        onSetMod: {
            js: {
                'inited': function() {
                    var sity_select = findBlockInside('cityselect');
                    city_select.on(this.domElem, 'change', this._onCityChanged, this);
                }
            }
        },
        _onCityChanged: function() {  ...  }
    }))
});

Как правильно указать событие и указать конкретный select?

Добрый день. Помогите плиз разобраться, как лучше поступить.

Есть хотелка подгружать блоки (стили и скрипты) только, когда они нужны, т.е. появились на странице или, в отдельных случаях, задействованы пользователем.

Проект собирается посредством webpack и хочется использовать его require.ensure(). Однако я не могу понять, как именно мне его использовать. На момент инициализации уже поздно грузить что-то - уже пора отрабатывать init`у (или можно как то Promise указать?), а запихать первой строчкой в module.define - рано, ведь define выполнится сразу...

Всем привет! Тут с утра написал код, который навешивает модификаторы на блок в зависимости от величина экрана. Всего три модификатора. Все работает, только прошу экспертного мнения, может так делать не стоит для продакшена, или есть другие варианты реализации (быстрее, менее ресурсоемкие и т.п.).

modules.define('main', ['i-bem__dom'], function(provide, BEMDOM) {

  provide(BEMDOM.decl(this.name, {
    onSetMod: {
      'js': {
        'inited': function() {


          if (BEMDOM.win.width() >= 840) {

            this.setMod('desktop');

          } else if (BEMDOM.win.width() >= 480 && BEMDOM.win.width() <= 839) {

            this.setMod('touch-pad');

          } else if (BEMDOM.win.width() <= 479) {

            this.setMod('touch-phone');
          }


          this.bindToWin('resize', function(e) {

            if (BEMDOM.win.width() <= 479 && this.hasMod('touch-pad')) {

              this.delMod('touch-pad');
              this.setMod('touch-phone');

            } else if (BEMDOM.win.width() >= 480 && BEMDOM.win.width() <= 839 && this.hasMod('touch-phone')) {

              this.delMod('touch-phone');
              this.setMod('touch-pad');

            } else if (BEMDOM.win.width() >= 480 && BEMDOM.win.width() <= 839 && this.hasMod('desktop')) {
              this.delMod('desktop');
              this.setMod('touch-pad');

            } else if (BEMDOM.win.width() >= 840 && this.hasMod('touch-pad')) {
              this.delMod('touch-pad');
              this.setMod('desktop', true);

            }

          });

        }
      }

    }
}));

});

На одном уровне переопределения блок B наследуется от блока A. На следующем оба блока переопределяются.

Common block A block B extends A

Desktop block A block B

Наследует ли блок B свойства блока A со всех последующих уровней переопределения?