Как при на событии одного блока, повлиять/повесить модификатор на блок в другой ветке документа? Ведь это должно быть возможным и кажется ответ где-то рядом.. Если у нас например:
modules.define('block1', ['i-bem__dom', 'jquery'], function(provide, BEMDOM, $) {
{
live: function() {
this.liveBindTo('block1-1', 'click', function( ) {
// как тут правильно обратиться к другому элементу вне блока?
// (block2).setMod('block2-1','current-block1-1',true);
// предполагал что-то вроде следующего, но скорей всего тут что-то совстем не так
this.findBlockOutside('block2').setMod('switched'); // Ошибка: this.findBlockOutside('block2') возвращает null, видать не дотягивается область видимости.
});
}
}
});
Появилась мысль, вешать модификаторы через общий документ (
) page.js. С первого раза почему .js в родительском файле совсем не заработал и ошибок не выдал, решил искать другой метод, не работает значит не надо :)Вычитал про наследование. Выполнил попытку следующего типа:
modules.define('bloack2', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, {}));
});
modules.define('block1', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, {
...
onSetMod : {
'switched' : function(){
this.__base.apply(this).setMod( 'visible', true); // Ошибка: TypeError: undefined has no properties
}
},
...
}));
});
Добился результата следующим методом, но знаю что он не рекомендуем:
onSetMod : {
'switched' : function(){
$('.block2').bem('block2-1').setMod( 'visible', true);
}
},
Помогите пожалуйста разобрать и сделать правильно.
Получше опиши, что за кейс. Что за блоки и почему один хочет менять другой. На вскидку: https://github.com/bem/bem-core/blob/v2/common.blocks/events/__channels/events__channels.vanilla.js Один блок размещает события в канале, другой на них реагирует. Но если посмотреть на кейс возможно найдутся ещё варианты.
@Guria, речь о подобии вашего проекта https://github.com/bem-projects-competition-2015/competition-with-loftblog/blob/master/review-6-tadatuta.md Только по проще и весь проект на bemhtml, потому ваш кейс же и не смог применить :)
в шапке "navicon"
по событию на нём появляется "sitebar" появляется. При этом sitebar на других разрешениях уже виден. Потому другая архитектура не очень приемлема. А то можно было бы хоть sitebar сделать потомком navicon и апсолютно позиционировать.
Собственно, вопрос заключался в том, чтобы с помощью i-bem.js в headernavicon.js по событию navicon модифицировать __sitebar.
Если я правильно понял вам нужен блок навигации. У него должно быть 2 элемента - кнопка в шапке и панель где-то в документе. При разрешении больше определённого кнопка скрыта, а панель видима, при меньших разрешениях панель скрывается и её видимость переключается кнопкой. Верно?
Если всё верно, то вам нужен Один JS-блок на нескольких HTML-элементах См. также обсуждения #227 и #237 В вашем случае это будет приблизительно так:
И ещё важные уточнения в #189
Спасбо, все абсолютно верно. Изучим..
Помогите более детально разобраться, пожалуйста. Концепт вроде стал ясен, но на практике применить не выходит =\ Из примера @Guria в моём случае, при миксовал я к обоим блокам my-nav.
В js технологии какого блока мне вешать события и реакцию, блока my-nav, в headernavicon или в pagesitebar. Логичней наверное в этом случае слушать header__navicon. Но для меня главный вопрос, область видимости элементов на которые я могу добавить событие и потом реакцию. К примеру почему не работает так:
header__navicon
иpage__sitebar
это не блоки, а элементы (которые, впрочем, могут содержать и блоки). По-умолчанию они не могут иметь (на самом деле нет, но вам пока это не надо) своего js представления. JS описывается именно для блока. События и реакция должны быть реализованы в блоке, который будет "знать" об обоих элементах. В вашем случае это либоpage
, либоmy-nav
который мы специально для этого и завели. Есть подозрение что у вас не очень удачная разбивка на блоки и элементы, но чтобы это утверждать надо изучить вашу реализацию подробнее.Спасибо @Guria, вы правы. На само деле я догадываюсь, что у меня много чего не правильно и стыдно показывать. Но судя по всему, если изначально не поправить, будет хуже :) Вот тут текущий проект https://github.com/Bumerang47/bem-as, буду рад критике.
в какой-то момент я так и решил, что надо на блок родителя всех родителей, вешать js и от туда всеми рулить. Создал page.js, в нём:
на page добавляется класс i-bem, но js не исполняется.
Ну вешать всё на
page
возможно, но не самый лучший вариант. По поводуpage
убедись, что вbemjson
указан атрибутjs: true
и файл у тебя называется page.js, а не paje.js как ты указал в комментарии.Да, названия теперь по 3 раза проверяю, а не по 2 ) js: true, указал в bemjson, хотя и в bemhtml тоже пробовал.
Накладок в проекте не мало, конечно. Обещать не стану, но если выберу время замечания накидаю.
@Guria и на том спасибо, уже очень помогли. Буду дальше учиться работать с модификаторами.
@Guria, могу ли я в js представлении блока обращаться не к элементам наследникам, а к наследникам блокам? Они ведь тоже своего роды элементы, только.. мм, блоки. конструкция такая:
this.liveBindTo('image', 'click', function(e) - срабатывает this.liveBindTo('PoPuPay', 'click', function(e) - нет
другая попытка добавить js блоку PoPuPay из конструкции выше. В каталоге блока service создал папку PoPuPay, в ней js:
Или при такой конструкции блок должен быть service__PoPuPay? =\
Можно и нужно. Все подробности в документации по i-bem. Смотри this.findBlock* и liveBindOnBlock* методы.
https://ru.bem.info/libs/bem-core/v2.6.0/desktop/i-bem/#Поиск-экземпляров-блоков-в-dom-дереве https://ru.bem.info/tutorials/bem-js-tutorial/03-live-initialization/ this.liveInitOnBlockInsideEvent
@Guria, подскажите пожалуйста как решить проблему. Два блока и если второй инициализируется (..js_inited) сперва, то события первого игнорируются. Это как-то связано судя по всему с важными уточнениями в #189. Но я не могу осознать причину и решения. При инициализации "serv-nav", "menu" все игнорирует.
@Bumerang47 в приведенном сниппете видимо что-то потерялось, т.к. там все блоки разные и друг друга никак аффектить не должны.
@tadatuta, вот я не могу понять где они друг друга аффектят. По каким причинам в принципе они могуд друг друга, ну того.. аффектить? Немного подправил сниппет:
Именно когда идет событие на serv-nav, на nav вешается serv-nav_js_inited, не наоборот. Вот тут полный листинг: https://github.com/Bumerang47/bem-as/blob/master/desktop.bundles/index/index.bemjson.js p.s. Простите, если я своим делитанским подходом на БЭМ, как-то задену БЭМ идеалы, я только учусь )
@Bumerang47
menu
ожидает, что в полеcontent
ему будут переданыmenu-item
(см. примеры использования). Вbem-components@2.1.0
мы даже добавили проверку на уровне шаблонов, чтобы нельзя было туда ничего другого положить. Кстати, сейчас можно и до 2.1.1 обновиться смело.js()('true')
и вserv-nav
в частности, а должно бытьjs()(true)
— булево значение вместо строки.Если эти два момента поправить, то инититься будет правильный блок.
@tadatuta, спасибо большое. Ключевой ошибкой тут были кавычки. Уже и не помню причину, по которой лукавый дёрнул руку их поставить, булево же, действительно, значение. Убрал кавычки, все работает как надо.
По поводу, "menu ожидает, что в поле content". Я тут вроде даже bem-components не использовал умышленно, просто одноименное название блока взял. Подумаю либо блок переименовать или использовать компонент как надо.
@Bumerang47
menu
изbem-components
вряд ли здесь подойдет, так что логичнее переименоватьТак то логичнее переименовать
menu
в bem-components :)