bem / bem-core

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

Add helper for getManyMod(elements, modName) #821

Closed mangin closed 9 years ago

mangin commented 9 years ago

Для получения значения модификатора документация предлагает использовать метод getMod. Но если в функцию getMod возвращает значение модификатора, только первого элемента.

Для решения этой проблемы я написал( под вдохновением функции setMod) следующий хелпер:

function getManyMod(elements, modName) {
    var block = this,
        result = [];
    elements.each(function () {
        var elem = $(this);
        elem.__bemElemName = block.__bemElemName;
        var mod = block.getMod(elem, modName);
        result.push(mod);
    });

    return result;
}

http://jsfiddle.net/sjycs2gL/ Мне бы хотелось узнать: на сколько законно так делать?

veged commented 9 years ago

название не очень понятное, скорее в нём должно присутствовать что-то про elems

а вообще не очень понятен кейс применения такой функции в реальной жизни — можешь привести пример?

mangin commented 9 years ago

С названием согласен.

Кейс: У меня есть следующий bem-json:

{
    "block": "layout",
    "content": [
        {"block": "layout", "elem": "col", "mods": {"id": "tiles"}},
        {"block": "layout", "elem": "col", "mods": {"id": "content"}},
        {"block": "layout", "elem": "col", "mods": {"id": "..."}}
    ]
}

Мне хотелось в декларации построить отображение: id -> elem

А затем уже для каждого элемента в декларации блока назначать специфические модификаторы, причем эти модификаторы изменяются динамически.

P.S. Я понимаю, что этот метод весьма специфичен и скорее всего не нужен всем. Мне просто хочется узнать на сколько законно до определять поле __bemElemName у jquery коллекции.

mangin commented 9 years ago

На самом деле мне хотелось метод что-то вроде GroupElementsByMod

veged commented 9 years ago

я очень боюсь, что так и не понял пример до конца :-/ что именно нужно потом делать с колонками лейаута?

пока мне кажется, что всё это должно решаться кастомным предметноориентированным кодом (причём как можно ближе к реальной задаче, возможно ещё выше чем GroupElementsByMod), а не добавками в базовый блок

трогать __bemElemName кажется пока очень грубым залезанием в кишки

mangin commented 9 years ago

У меня есть общий много-колоночный layout для нескольких сайтов и single page application.

В декларации блока layout я создал метод позволяющий по конфигурации вида id -> pos&width устанавливать модификаторы gridblock_pos_Number и gridblock_width_number на колонку с определенным модификатором.

Затем код layout я поместил в базовую сборку блоков, а пользователи блока должны будут унаследоваться от layout и до определить у него более красивые функции вида: 1) Скрыть колонки с навигацией 2) Показать колонки с навигацией и тд.

Какие колонки будут в лайауте мне не известно. Мне известно что структура html будет описываться следующим json:

{
    "block": "layout",
    "mix": [{
        "block": "grid",
        "mods": "grid_size_24"
    }],
    "content": [{
        "elem": "col",
        "mods": {
            "id": "tiles"
        },
        "mix": [{
            "mods": [{
                "block": "grid",
                "elem": "block"
            }]
        }]
    }, {
        "elem": "col",
        "mods": {
            "id": "content"
        },
        "mix": [{
            "mods": [{
                "block": "grid",
                "elem": "block"
            }]
        }]
    }, {
        "elem": "col",
        "mods": {
            "id": "..."
        },
        "mix": [{
            "mods": [{
                "block": "grid",
                "elem": "block"
            }]
        }]
    }]
}

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

Для решение поставленной задачи мне необходимо запомнить элементы gridblock и соответствие gridblock <-> layout_coltype*.

mangin commented 9 years ago

Так же можно было сказать что каждая колонка это элемент вида layout_id, но тут засоряется namespace модификаторов, поэтому такой подход мне тоже не сильно по душе.

veged commented 9 years ago

какой-то странный bemjson:

        "mix": [{
            "mods": [{
                "block": "grid",
                "elem": "block"
            }]
        }]
veged commented 9 years ago

кажется, что всё должно описываться просто кастомным кодом через какой-нить map от набора элементов

mangin commented 9 years ago

Ой извиняюсь, за ошибку в бэм-json(у нас к сожалению, в команде пишут все на nunjucks)

"mix": [{
            {
                "block": "grid",
                "elem": "block"
            }
        }]

Я задачу и решил, через each(почти-тоже самое что и map), но: 1) map - возвращает в колбеке dom-element 2) При оборачивании $ естественно свойство .__bemElemName теряется, поэтому я его сам дописывал.

Было бы круто, если операции, которые возвращали не jquery коллекцию, а некоторую bem-jquery коллекцию с методами map or forEach, которые поддерживали свойство __bemElemName