bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Не могу правильно примиксовать стили к блоку select #1160

Open vokson opened 7 years ago

vokson commented 7 years ago

Добрый день, Не могу понять в чем дело. Наверное, какая-то глупая ошибка. Я пытаюсь примиксовать стили к input и select в блоке qa-form.

.bemjson.js

        block: 'qa-form',
        url: "http://guk/api/feedback",
        content: [
            {
                elem: 'fields',
                content: [
                    {
                        block: 'input',
                        mods: {'has-clear': true},
                        name: 'flexibility'
                    },
                    {
                        block: 'select',
                        mods: {mode: 'radio'},
                        name: 'slenderness',
                        val: 1,
                        options: [
                            {val: 1, text: 'Report'},
                            {val: 2, text: 'Workshop'},
                            {val: 3, text: 'Round-table conference'}
                        ]
                    }
                ]
            }
        ]

qa-form.bemhtml.js

block('qa-form') ( js()(true),

tag()('form'),

block('input').mix()({  mods: {theme: 'islands', size: 'm'} }),
block('select').mix()({mods: { theme: 'islands', size: 'm'}}),

attrs()(function () {
    return {action: this.ctx.url};
})

);

qa-form.deps.js ({ mustDeps: [ {block: 'input', mods: {theme: 'islands', size: 'm'}}, {block: 'select', mods: {theme: 'islands', size: 'm'}}, ] })

В результате для input стили подключаются, а для select нет. Позже я понял, что внутри select есть блоки button и popup, для которых стили не подключаются. Если сделать так:

qa-form.bemhtml.js

block('qa-form') ( js()(true),

tag()('form'),

block('input').mix()({  mods: {theme: 'islands', size: 'm'} }),
block('select').mix()({mods: { theme: 'islands', size: 'm'}}),
block('button').mix()({mods: { theme: 'islands', size: 'm'}}),
block('popup').mix()({mods: { theme: 'islands', size: 'm'}}),

attrs()(function () {
    return {action: this.ctx.url};
})

);

qa-form.deps.js ({ mustDeps: [ {block: 'input', mods: {theme: 'islands', size: 'm'}}, {block: 'select', mods: {theme: 'islands', size: 'm'}}, {block: 'button', mods: {theme: 'islands', size: 'm'}}, {block: 'popup', mods: {theme: 'islands', size: 'm'}}, ] })

То стили подключаются и для select, но он не работает (кнопка не нажимается). Видимо почему-то js не подключается.. P.S. Извините, не понял как здесь правильно вставлять код, чтобы все было красиво.

tadatuta commented 7 years ago

Код оформляется в markdown в точности как на github — три бектика и язык для подсветки кода (комментарий можно отредактировать).

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

Если необходимо выразить «Добавь микс к любому блоку input внутри блока qa-form», то это должно выглядеть примерно вот так:

block('qa-form')(
    def()(function() {
        return applyNext({ _inQaForm: true }); // выставляем флаг _inQaForm, который будет доступен из всех узлов внутри данного
    }),
    tag()('form'),
    // ...
);

block('input').match(function() {
    return this._inQaForm; // подпредикат, который проверяет, что флаг взведен
}).mix()({mods: { theme: 'islands', size: 'm' });

Но на самом деле я бы так не извращался и писал все это явно, а еще лучше — ввел бы слой с BEMTREE. Ну а если очень хочется сэкономить на повторении модификаторов, я бы скорее предложил написать универсальный шаблон на все контролы безотносительно контекста:

block('input').def()(function() {
    var mods = this.mods;

    if (!mods.theme) {
        mods.theme = 'islands';
    }

    if (!mods.size) {
        mods.size = 'm';
    }

    return applyNext();
});

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

tadatuta commented 7 years ago

Слава @miripiruni, историю про умолчания и «вложенные предикаты» стоит добавить в какой-нибудь FAQ — часто спрашивают.

vokson commented 7 years ago

Спасибо за помощь. Сделал по последнему варианту.

miripiruni commented 7 years ago

@tadatuta пример с applyNext({ _inQaForm: true }) огонь. Давай заведём issue на дополнение документации.