Выявил особенность работы с модификаторами одного js блока на нескольких DOM-нодах:
- установка и удаление мода из
i-bem
изменяет соответствующий класс на всех нодах блока - если при инициализации у DOM-нод набор модификаторов отличается, то первый вызов метода
hasMod
имеет некоторые особенности:
{ block: 'a', mods: { foo: 'bar'}, js( { id:1})},
{ block: 'a', js( { id:1})}
> this.hasMod('foo')
true
> this.toggleMod( 'foo', 'bar').getMod( 'foo')
""
{ block: 'a', js( { id:1})}
{ block: 'a', mods: { foo: 'bar'}, js( { id:1})},
> this.hasMod('foo')
false
> this.toggleMod( 'foo', 'bar').getMod( 'foo')
"bar"
Возможные последствия:
- первый вызов toggleMod может не выполнить то, что возможно ожидалось
- стили модификатора могут повлиять на элемент, для которого они не предназначались
Способы решения:
- одинаковые модификаторы на всех нодах блока при инициализации
- стилизовать элементы по модификатору специфичным селектором
#asktheteam
- данные особенности стоит отразить в документации
console.warn("unambigios mods set on block's nodes. see http://bem.info/... for more info")
при инициализации в девелопер режиме P.S. если способа добавлять js код специфичный для девелопер режима сейчас нет, рассматривать это как отдельный фичреквест
@dfilatov Дима, что думаешь?
Я не рассматривал варианты изменения поведения самих методов в
i-bem
, оставив этот вопрос на усмотрение командыbem-core
А мы точно никак не можем собирать все модификаторы со всех
блоковдом-нод и синхронизировать их? Неприятная штука.Нет, мы не должны хотеть синхронизировать модификаторы у блоков на нескольких дом-нодах. Представим себе ситуацию, когда один и тот же модификатор на разных нодах имеет разные значения. Какой должен оказаться итоговым? Сразу скажу, что завязываться на порядок этих элементов в DOM'е плохая идея. И это не единственная проблема.
@dfilatov так дело именно в том, что после запуска
setMod
/removeMod
мод установится/уберется на всех дом нодах.@Guria Я не понимаю, о чем именно это говорит
@dfilatov Перечитал ещё раз. Не увидел сразу, что речь о разных значениях. Предложения остаются прежними: документировать и предупреждать в дев режиме.
Про подумать про дебаг-режим есть таск: https://github.com/bem/bem-core/issues/836, можно дописывать свои предложения туда
@dfilatov В любом случае, что-то сделать нужно. Может быть дать возможность выставлять модификаторы не на инстанс блока, а на domElem?
В данный момент у нас при инициализации одно поведение, и после — другое. Т.е. либо setMod должен выставлять модификатор только у того же, у которого он проверяет модификатор. Либо hasMod должен проверять модификатор у всех.
Правильнее всего, либо синхронизировать их насильно, собирая все модификаторы, либо, при использовании механизма
js: { id : Number }
, как-то запрещать или срать варнингами в дебаг режиме, что это может сломаться, и нужно указывать явно дом-ноду, на которой нужен модификатор.Но в случае со множественными дом-нодами и отдельными модификаторами на них есть еще одна проблема — в этом случае onSetMod должен принимать target, чтобы понимать, где именно он сменился, логика ломается.
Может быть стоит переосмыслить эти множественные дом ноды?
@zxqfox Модификатор — это неотъемлемая часть блока, не может блок быть в таком непонятном состоянии. И не надо js заставлять исправлять "косяки", пришедшие ему из верстки. Про дебаг-режим ответил выше.
@dfilatov Я и не предлагаю. Я говорю, что текущая логика неконсистентна и непредсказуема без знания деталей реализации. Это, естественно, зло.
Хотел бы понять, как с твоей точки зрения правильнее это решить: контролировать bemjson и хтмл-выдачу?
cc @veged
Идиотская идея: pseudo-блоки.