bem / bem-core

BEM Core Library
https://ru.bem.info/technologies/classic/i-bem/
Other
275 stars 94 forks source link

i-bem.bemhtml: BEMJSON для элемента зависящего от модификаторов блока должен работать #1026

Open voischev opened 9 years ago

voischev commented 9 years ago

Привет. Встретил такой кейс. Нужно от шаблонизировать элемент блока-с-модификатором в браузере

Шаблон

block('block').mod('foo', 'bar')(
    ...,
   elem('result')(
        mix()(function() {
            return { block : 'block', elem : 'text' };
        }),
        content()(function() {
            return [
                'Тексты',
                {
                     block : 'link',
                     url : 'url',
                     content :  'и другие блоки внутри'
                }
            ];
        })
    )
)

Элемент result хочется отшаблонизировать на клиенте

modules.define(
    'block',
    ['BEMHTML'],
    function(provide, BEMHTML, Block) {
    provide(Block.decl({ modName : 'foo', modVal : 'bar' }, {

        onSetMod : {
            'js' : {
                'inited' : function() {
                    console.log(BEMHTML.apply({
                        block : 'block',
                        mods : { foo : 'bar' },
                        elem : 'result'
                    }));
                }
            }
        }
    }));
});

Результат

[Log] <div class="block__result block__result_foo_bar block__text">...</div> 

Все как нужно, но block__result_foo_bar Который совсем не нужен, который совсем не ожидаешь.

Почему так? Как поступать в таких случаях?

tadatuta commented 9 years ago

Плохой вариант:

$(BEMHTML.apply({
    block : 'block',
    mods : { foo : 'bar' },
    content : {
        elem : 'result'
    }
})).find(this.buildSelector('result')).html();

Хороший вариант: сделать result самостоятельным блоком, смиксованным с block__result.

qfox commented 9 years ago

Кажется, что BEMHTML должен уметь делать что-то типа:

BEMHTML.with({block:'block', mods: {foo: 'bar'}}).apply...
voischev commented 9 years ago

Почему нельзя использовать elemMods для элемента, а mods только для блока?? Зачем оно на элемент прокидывается?

qfox commented 9 years ago

@voischev Я вообще не знаю зачем оно в bemjson. Для bemhtml — не знаю зачем в шаблоны пробрасывается. Не увидел убедительных доводов: https://github.com/bem/bem-method/issues/250

Guria commented 9 years ago

@voischev @zxqfox Похоже у вас разные точки зрения на этот счёт :)

qfox commented 9 years ago

@Guria сходимся в том, что все это неоднозначно и стоит причесать ;-)

narqo commented 9 years ago

Почему нельзя использовать elemMods для элемента, а mods только для блока?? Зачем оно на элемент прокидывается?

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

Поведение уходит далеко в прошлое и базируется на идее «элемент у блока с модификатором невозможен». А раз block_mod_val__elem невозможен, то можно немного с оптимизировать и схитрить.

Можно (в теории) обойти так:

apply({
  block : 'block',
  mods : { foo : 'bar' },
  elemMods : {},  // NOTE `elemMods`
  elem : 'result'
})
tadatuta commented 9 years ago

В bem-xjst@4.0.1 поведение совпадает:

BEMHTML.apply({ block: 'b1', elem: 'e1', elemMods: { m1: 'v1' } }); // '<div class="b1__e1 b1__e1_m1_v1"></div>'

BEMHTML.apply({ block: 'b1', elem: 'e1', mods: { m1: 'v1' } });     // '<div class="b1__e1 b1__e1_m1_v1"></div>'
qfox commented 9 years ago

И это замечательно!

narqo commented 9 years ago

@tadatuta плохо, может исправить, до bem-core@3.x?

tadatuta commented 9 years ago

@narqo завел https://github.com/bem/bem-xjst/issues/88

voischev commented 9 years ago

:+1: