Здравствуйте, я новичок в 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?
Привет!
Нужно смиксовать каждый
select
с соответствующими элементами блокаfilter-form
, тогда уfindBlockInside()
можно будет передать контекст:Однако можно подписываться на делегированные события, что на самом деле зачастую более удобно.
Спасибо за подробный ответ! Странно, сначала работало, теперь перестало после нескольких перезагрузок страницы Может js неправильно подключаю? Я делаю так:
В filter-form.js только modules.define('filter-form'...). Может его надо обрамлять в
Хотя тоже не помогает. filter-form почему-то не js-inited
@oekintaro у меня для такого HTML
и такого JS работает как ожидается:
Спасибо! Все работает!
@tadatuta Все же не работает) точнее не всегда работает.
Почему-то блок filter-form не всегда инициализируется. Вроде бы инициализация должна произойти, когда загрузится полностью DOM. Вот сам сайт - m2center.ru static/outsite/js/filter-form.js - здесь js код filter-form кнопка выбора города - это элемент filter-form__city
Уже голову сломал. Если посмотрите, буду очень благодарен.
Проблему понял, она связана с тем, что инициализация блоков на странице иногда происходит до того, как успевает произойти декларация
filter-form
.Я добавлю возможность самостоятельно управлять моментом инициализации.
Пока в качестве быстрого хака могу предложить такую схему:
перенести из него в свой проектный код и вызывать после всех вызовов
modules.define()
.Спасибо! Теперь точно работает))
Здравствуйте! У меня по сути тот же самый вопрос, но по bem-components 6.0.0. Не удается отловить событие 'change' селектора (select).
Привожу содержимое ads-list-form-search.js:
Выдержка из ads-list-form-search.bemhtml.js (только элемент control-brand):
Подключение зависимостей в ads-list-form-search.deps.js:
Реакции на событие событие 'change' не наблюдается. Подскажите пожалуйста, где тут ошибка. Спасибо!
@sermonis
Ошибка собственно в подписке на событие (
this._events(Select).on(this._elem('control-brand'), 'change', this._onBrandChanged, this);
).Если по какой-то причине ленивая инициализация действительно не нужна, то должно сработать такое:
А для обеспечения ленивой инициализации стоит создать отдельную декларацию для самого элемента
control-brand
, в нем подписаться на селект и бросить собственное событие, которое потом ловить из родительского блока.@tadatuta
Все работает. Большое спасибо за помощь! Создал отдельную декларацию для элемента
control-brand
. На всякий случай приведу здесь итоговый пример кода для bem-components 6.0.1., может кому-то пригодится.Выдержка из ads-list-form-search.bemhtml.js (родительский блок):
Содержимое ads-list-form-search__control-brand.deps.js:
Содержимое ads-list-form-search__control-brand.js: