Войти с помощью github

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

Делаю примерно так:

var lazyBlock = this.findChildBlock(SomeLazyBlock);
this._events(lazyBlock).on('someEvent', this.onSomeEvent);

Но во время findChildBlock оно уже автоматически инициализируется, так?

Существует ли способ сохранить неинициализированное состояние и при этом реагировать на события?

Есть примерно следующая структура вложенных блоков:

{
    block : 'box',
    mods : {
        root : true,
        id : 'layoutBox',
    },
    content : {
        block : 'box',
        mods : {
            id : 'appBox',
        },
        // Имеем некоторую вложенность блоков `box`: layoutBox->appBox->ReportLayout->Report->ReportDisplay; Т.е.:
        // ...
        content : {
            block : 'ReportDisplay',
            mix : {
                block : 'box',
                mods : {
                    id : 'ReportDisplay',
                },
            },
            content : {
                // Some content...
            },
        },
    },
}

При удалении блока ReportDisplay (при помощи BEMDOM.destruct(ReportDisplay.domElem)) по цепочке parentNode (в jquery) до верхнего уровня (layoutBox) всплывает событие на delMod('js'), в результате чего блок отписывается от событий, зарегистрированных на window (ранее подписываемся так: this._domEvents(BEMDOM.win).on('resize',...)).

Стек выглядит примерно так:

    (i-bem-dom__events.js:155) this._storage[e] = null; // e='resize' -- Это собственно удаление подписанного события в _unbindByEvent.
    // ...
    (i-bem-dom__events.js:139) objects.each(this._storage, this._unbindByEvent, this); // this._storage={resize:{uniq161:{...}}}
    (i-bem-dom__events.js:253) params.bindToArbitraryDomElem && ctxStorage[storageKey] &&
                            ctxStorage[storageKey].un();
    (i-bem-dom__events_type_bem.js:85) fn.call(fnCtx || instance, originalEvent, data); // fnCtx=null, instance=layoutBox, originalEvent={bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (jquery:5205) ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||     //  handleObj.origType='__bem__box_js_'
                        handleObj.handler ).apply( matched.elem, args ); //  matched.elem=layoutBox.domElem[0], args=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:5014) jQuery.event.dispatch.apply( elem, arguments ); // elem=layoutBox.domElem[0], ...
    (jquery:8201) handle.apply( cur, data ); // cur=layoutBox.domElem[0], data=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:8262) jQuery.event.trigger(type, data, this); // type='__bem__box_js_', data=[{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}], this=ctx
    (jquery.js:8269) ctx.domElem.trigger(event, [data, { fns : {}, propagationStoppedDomNode : null }, originalEvent]); // event='__bem__box_js_', data={modName:'js',modVal:'',oldModVal:'inited'}, originalEvent:{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}
    // ...
    (i-bem-dom.js:676) bemEvents.emit(this, e, data); // e={modName:'js',modVal:''}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (i-bem-dom.js:733) this._emit({ modName : 'js', modVal : '' }, eventData); // eventData={modName:'js',modVal:'',oldModVal:'inited'}
    (i-bem.vanilla.js:324) this._afterSetMod('js', '', 'inited');
    (i-bem.vanilla.js:382) this.setMod('js', '');
    (i-bem.vanilla.js:247) this.delMod('js');
    (i-bem-dom.js:244) entity._delInitedMod();
    (i-bem-dom.js:1004) removeDomNodeFromEntity(entity, domNode);
    // ...
    (i-bem-dom.js:1029) this._destruct(ctx, excludeSelf, true);
    BEMDOM.destruct(ReportDisplay.domElem);

Полностью слепок вершины стека из DevTools, от destruct до _unbindByEvent).

_unbindByEvent (i-bem-dom__events.js:155)
each (objects.vanilla.js:56)
un (i-bem-dom__events.js:139)
(anonymous) (i-bem-dom__events.js:254)
inherit._createEventManager (i-bem-dom__events_type_bem.js:85)
dispatch (jquery.js:5206)
jQuery.event.add.elemData.handle (jquery.js:5014)
trigger (jquery.js:8201)
(anonymous) (jquery.js:8269)
each (jquery.js:362)
each (jquery.js:157)
trigger (jquery.js:8268)
emit (i-bem-dom__events_type_bem.js:119)
_emit (i-bem-dom.js:676)
_afterSetMod (i-bem-dom.js:733)
setMod (i-bem.vanilla.js:324)
delMod (i-bem.vanilla.js:382)
_delInitedMod (i-bem.vanilla.js:247)
removeDomNodeFromEntity (i-bem-dom.js:244)
(anonymous) (i-bem-dom.js:1004)
each (objects.vanilla.js:56)
(anonymous) (i-bem-dom.js:1000)
each (jquery.js:362)
each (jquery.js:157)
_destruct (i-bem-dom.js:993)
destruct (i-bem-dom.js:1029)

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

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

Хелп? Что это может быть?

Версии библиотек:

  • bem-core@4.2.1
  • jquery@3.2.1

Всем доброго времени суток. Появилась необходимость доопределить js для блока Attach. А именно, при выборе картинки рисовать preview аватара. Код:

/* desktop.blocks/attach/attach.js */
modules.define('attach', function(provide, Attach) {
    provide(Attach.decl({ modName: 'type', modVal: 'avatar' }, {
        onSetMod: {
            'js': {
                'inited': function() {
                    this.__base.apply(this, arguments);
                    console.log('attach_type_avatar inited...');
                }
            }
        },
        _updateFileElem: function() {
            this.__base.apply(this, arguments);
            console.log('_updateFileElem');
            //Do something...
        },
        _clear: function() {
            this.__base.apply(this, arguments);
            console.log('_clear');
            //Do something...
        }
    }));
});

Методы срабатывают, "Супер-колл" работает, Функциональность блока не ломается, только после выбора файла, всплывает ошибка:

Uncaught TypeError: Cannot read property '_emitChange' of undefined at Object._onChange (profile_settings.min.js:7695) at n.fn.init. (profile_settings.min.js:1643) at Function._liveClassTrigger (profile_settings.min.js:1618) at HTMLBodyElement.f (jquery.min.js:2) at HTMLBodyElement.dispatch (jquery.min.js:3) at HTMLBodyElement.r.handle (jquery.min.js:3)

Конкретно в этом месте:

_onChange : function() {
        this.elem('no-file').detach();
        this.getVal()?
            this
                ._updateFileElem()
                ._emitChange() :
            this._clear();
}

Как побороть ошибку? Доопределяю кнопки таким же образом - нет никаких ошибок.

Добрый день!

Подскажите, пожалуйста как правильно подключить скрипт по URL используя loader. Посмотрел для примера принцип подключения jQuery и сделал по аналогии, но скрипт не подключается. Не могу разобраться что я упустил.

dropzone.deps.js:

({
    mustDeps: [ 'i-bem-dom' ],
    shouldDeps: [
        { block: 'loader', mods : { type : 'js' } },
        { elem: 'config' },
        { mods: { theme: ['islands', 'default'], size: ['s', 'm', 'l', 'xl'], width: ['available'] } },
    ]
})

dropzone.bemhtml.js:

block('dropzone')(
    tag()('form'),
    attrs()({ action: '/post' }),
    addJs()(true)
);

dropzone__config.js:

/**
 * @module dropzone__config
 * @description Configuration for Dropzone
 */

modules.define('dropzone__config', function(provide) {

    provide(/** @exports */{

        /**
         * URL for loading Dropzone (http://www.dropzonejs.com)
         * @type {String}
         */
        url: 'https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.1.1/dropzone.js',
    });

});

dropzone.js:

/**
 * @module dropzone
 */
modules.define('dropzone', ['i-bem-dom', 'loader_type_js', 'dropzone__config'],

    function(provide, bemDom, loader, cfg)
    {
        const Dropdown = bemDom.declBlock(this.name, {

            /**
            * On modifier set
            * callback functions
            */
            onSetMod: {

                js: {

                    /**
                    * @param modName
                    * @param modVal
                    * @param currentModVal
                    */
                    inited() {

                        console.log('Dropzone - inited()');

                    }
                }
            },

        }, {
            lazyInit: false,

            onInit() {

                console.log('Dropzone - onInit()');
                return this.__base.apply(this, arguments);
            },

        });

        function doProvide(flag = 'defined')
        {
            console.log('Dropzone - doProvide(' + flag + ')');
            provide(Dropzone);
        }

        typeof Dropzone !== 'undefined' ? doProvide('undefined') : loader(cfg.url, doProvide);

    }
);

console.log:

Dropzone - doProvide(defined)
Dropzone - onInit()
Dropzone - inited()

Приветствую всех!

Помоги мне советом пожалуйста, как правильно при использовании bem-express мне использовать уровни при рендере для тач допустим?

Спасибо! Все будет bem :D

Начал перетаскивать проект на новые версии bem-components, bem-core. После банальных переименований методов упёрся в непонятное:

Что использовать вместо:

  • elem = block.elemify(domNode, 'elem')
  • block = domNode.bem('block') (найдено; но, блин... знаете...)

(Также предстоит ещё разбираться с кучей мест, где используется старый menu-item вместо menu__item. Наверное, что-то ещё вылезет; приду сюда плакать обратно.)

Добрый день. Заразился БЭМ) пока только пробую и учусь.

Хочу потестить bem-grid но без project-stub и собственно без полноценной БЭМ разработки, по простому так сказать. Установил новый модуль себе в проект: npm i --save-dev bem-grid. Подтягиваю стили из модуля, все нормально работает) Решил поменять настройки сетки, но не пойму где именно и как пересобрать новый css, какую комманду в консоли ввести? Спасибо

Добрый вечер!

Начал проект на свежей версии bem-core. Предыдущая была - 3.2.0, в связи с этим возникло много вопросов, и этот - самый проблемный. У меня прекрасно ищутся элементы:

this.findChildElem({elem: 'row', modName: 'error', modVal: true})

Но вот при попытке найти аналогичным образом блок

this.findChildBlock({block: 'input', modName: 'email', modVal: true})

Мне валится ошибка: Block must be a class or description (block, modName, modVal) of the block to find.

На странице https://ru.bem.info/platform/i-bem/dom/ пример вообще достаточно странный:

modules.define('attach', ['i-bem-dom', 'button'], function(provide, bemDom, Button) {

provide(bemDom.declBlock(this.name, {
    onSetMod: {
        'js': {
            'inited' : function(modName, modVal) {
                this._button = this.findChildBlock(Button);
            }
        }
    }
}));

});

Из него вообще не понятно, как мне найти внутри блока 'attach', например, блок 'button' такого вида:

{ block: 'button', modName: 'foo', modVal: 'bar' }

Подскажите, пожалуйста, что я делаю не так?

Здравствуйте. В стандартной сборке bem уже есть jquery, на данный момент там версия 3.1.0. Провайдим, пользуемся, всё отлично, спасибо. НО: Вопрос следующего характера: как "bem-правильно" выплюнуть jquery в глоб. пространство, чтобы jquery было доступно из консоли в браузере ( сейчас ни jQuery, ни $ не видит) ?

Спасибо!

На основе project-stub создал репозиторий Создал блок fancybox, реализация js, css.

jquery.fancybox.js подключается, с этим вопросов нет.

Но консоль выдает ошибку о неизвестном аргументе - jQuery

  • Если в bemjson.page, в теле head прописываю явно - jQuery брать с cdn, то проблем нет.
  • То есть загрузка по умолчанию добавляет jQuery в последнюю очередь, в следствии чего jQuery is not defined

По умолчанию загрузка jQuery - быстрее всего - 3-5ms Явно - jQuery брать с cdn - 200-300ms

Вопросы: 1) Как сделать что бы fancybox работал с загрузкой jQuery которая по умолчанию. mustDeps - не помогают. 2) В чем магия со скоростью загрузки? 3) cdn Яндекс быстрее, чем cdn Гугла - это только у меня?

Добрый вечер! Помогите, пожалуйста, со следующей проблемой. Имею такой bemjson:

module.exports = {
    block: 'page',
    title: 'Authorization',
    head : [
        { elem : 'meta', attrs : { name : 'description', content : '' } },
        { elem : 'css', url : 'index/index.css' }
    ],
    scripts: [{ elem : 'js', url : 'index/index.js' }],
    content: {
        block: 'wrapper',
        content: {
            block: 'auth'
        }
    }
}

Вот такой шаблон:

block('auth')(
    js()(true),

    content()(() => {
        return 'Hello, world!'
    })
)

И вот такое вот js объявление блока:

modules.define('auth', ['i-bem__dom'], function(provide, BEMDOM) {
    provide(BEMDOM.decl(
        this.name,
        {
            onSetMod: {
                'js': {
                    'inited': function() {
                        console.log('auth inited');
                    }
                }
            }
        }
    ))
});

Не происходит инициализация блока 'auth'. Не могу понять, где ошибка: имя блока в шаблоне и декларации совпадают, js в шаблоне включен, в зависимостях page'а автоматическая инициализация тоже прописана. В результирующий js декларация попала, js на страницу - тоже. В консоль никаких ошибок не валится. Класс i-bem в html-разметке тоже присутствует:

<div class="auth i-bem" data-bem="{&quot;auth&quot;:{}}">Hello, world!</div>

Привет. Я сделал модификатор input, который добавляет очень полезные функции. Можно ли использовать этот модификатор у наследника input - у textarea? Или это решается только через миксины?

Здравствуйте! Довольно наболевшая для меня тема, вот дошли руки написать. Есть несколько вопросов по вот этой сборке: https://github.com/bem/project-stub

  1. Как должен выглядеть файл make.js чтобы собирался merged bundle (самому написать пока-что представляется сложным, говорят нужно nodejs учить), что-то мне кажется инфа с bem.info про сборку merged бандла устарела. Ну и так как собирать можно не только enb, но и gulp'ом, как должен выглядеть gulpfile.js?

  2. Допустим я пишу в phpStorm, в сборках более ранних версий я без проблем писал на stylus или sass. Но postCSS (.post.css || .pcss) не поддерживается в шторме (да плагинов рабочих я для него не сыскал), и следственно написание postCSS вызывается сложности в виде 100500 подчеркиваний красной волнистой ну и файлы css не понимают синтаксиса (капитан очевидность). Кто-нибудь видит адекватное решение в такой ситуации?

  3. Как прикрутить к последней сборке sass вместо postcss (ну нравится мне sass/scss :) ) ???

Мне кажется было бы неплохо если бы в стандартной сборке был бы предусмотрен свитч между препроцессорами (какие человеку нравятся ну или хотябы sass||postCSS) , а так же между обычной сборкой и merged, удобно ведь было бы)

Привет!

Мы, наконец, выпустили новые версии bem-core и bem-components!

bem-core 4.2.0

Версия полностью обратносовместимая, так что обновление должно быть совершенно «бесплатным».

Главным изменением является совместимость с bem-xjst 8.x. Кроме того в версию вошла большая работа по переводу документации на английский и, конечно же, исправления ошибок и мелкие улучшения. Подробности читайте в changelog.

bem-components 5.1.0

Версия также является обратносовместимой и не должна требовать никаких усилий при обновлении.

В ней обновлена зависимость от bem-core до 4.2.0, добавлено визуальное оформление для link_disabled и исправлены некоторые ошибки.

Подробности в changelog.

bem-components 6.0.0

Эта версия обязательно требует обновления до bem-xjst 8, где появились новые полезные режимы и исправлена работа режима extend. Необходимые пакеты для сборки на ENB (enb-bemxjst 8.6.7) или gulp (gulp-bem-xjst 3.0.0) уже доступны для установки.

При переходе вам может пригодиться автоматический мигратор шаблонов: https://github.com/bem/bem-xjst/tree/master/migration#migration-tool-for-templates

Кроме новых шаблонов версия ничем не отличается от 5.1.0.

Где попробовать

Свежие bem-core 4.2.0 и bem-components 6.0.0 уже внедрены в project-stub.

Если при обновлении у вас возникнут какие-либо проблемы — пишите, мы постараемся помочь.

Добрый вечер, подскажите пожалуйста есть ли в стеке bem библиотека tab? Найдя ссылку на одно из библиотек: https://github.com/bem-contrib/hackaton/tree/master/common.blocks/tabs, столкнулся с такой проблемой, что переключения вроде бы и есть, но переключение срабатывает только в 1 случае (Идёт смена контента), при дальнейших дейтсвиях, появляются уже оба контента.

Добрый день, столкнулся с такой проблемой:

Имеется блока "content" - <div class="content i-bem"><div class="content__wrap">...</div> и его js:

modules.define(
    'content',
    ['i-bem__dom', 'jquery', 'location'],
    function (provide, BEMDOM, $, location) {

    provide(BEMDOM.decl(this.name, {
        onSetMod: {
            js: {
                inited: function () {
                    this._loader = this.findBlockInside('loader');
                    location.on('change', this._onChangeLocation, this);
                }
            },

            loading: {
                true: function () {
                    this._loader.setMod('progress', true);
                },

                '': function () {
                    this._loader.delMod('progress');
                }
            }
        },

        _loadIssues: function (options) {
            var uri = location.getUri();
            options.url = uri.getQuery();
            this._sendRequest(options);
        },

        _onChangeLocation: function (e, state) {
            var uri = location.getUri(),
                options = {};

            this._loadIssues(options);
        },

        _sendRequest: function (options) {
            this._abortRequest();

            this.setMod('loading', true);

            this._xhr = $.ajax({
                type: 'POST',
                dataType: 'html',
                url: options.url,
                data: {
                    jsonContent: true,
                },
                cache: false,
                context: this
            }).fail(function () {
                console.log(fail);
            }).done(function (html) {
                this._onSuccess(html);
            })
            .always(function () {
                this.delMod('loading');
            });
        },

        _abortRequest: function () {
            this._xhr && this._xhr.abort();
        },

        _onSuccess: function (html, type) {
            type = type || 'update';
            this._render(html, type, 'wrap');
        },

        _render: function (html, addMethod, elem) {
            var wrap = (elem && this.elem(elem)) || this.domElem;

            BEMDOM[addMethod](wrap, html);
        }
    }));
});

Суть проблемы в том, что когда мы подгружаем какой-то блок через ajax (Пусть будет "base"), 1 раз live функция срабатывает, но если вдруг мы вызовем другой блок (base1) и затем заного base, тот функция live уже не срабатывает, в следствии чего, не срабатывает и функция. (Пример) :

modules.define('base', 
    ['i-bem__dom', 'BEMHTML', 'jquery', 'events__channels',  'base-rows'],
    function(provide, BEMDOM, BEMHTML, $, channels) {
        provide(BEMDOM.decl(this.name, {
            onSetMod: {
                'js' : {
                    inited: function() {

                    }
                }
            },

            _onScroll: function() {
                $('.base-body').scrollbar();
                $('.base-body').height($(window).height() - 195);
                $('.base-body').scrollbar();
                $(window).resize(function () {
                    $('.base-body').height($(window).height() - 195);
                });
            },

            _getBaseUpdate: function() {

            }
        }, {
            live: function() {
                this.prototype._onScroll();

                this
                    .liveBindTo('update', 'pointerclick', this.prototype._getBaseUpdate());
            }
        }));
    }
);

Первый раз, когда мы подгружаем блок <div class="base i-bem">...</div>, функция live срабатывает и вследствии чего, функцию _onScroll он вызывает, он если мы вызовем другой блок через ajax, а потом заново base, то уже функция _onScroll не срабатывает.

Подскажите, пожалуйста, как можно сделать, чтобы при каждом вызове через ajax, блок base, срабатывала автоматически функция _onScroll.

Всем привет! Опять с вопросом! Обновился до bem-core 4.1.1 и обнаружил засаду. Простая операция, закрытие модального окна по крестику, не поддается. Может есть примеры реализации простых операций на новой версии, для особенно "одаренных", например как тут http://bem.github.io/bem-bl/sets/common-desktop/i-bem/i-bem.ru.html

код файла modal_has-close.js

modules.define('modal', function(provide, Modal) {

provide(Modal.declMod({modName: 'has-close'}, {
    onInit : function() {
        this._domEvents('close').on('click', function() {
            this.delMod('visible');

        });
    }
}
));

});

PS уроверь знаний js не начальный, но переход на БЭМ дается почему-то очень тяжко.

Привет помогите пожалуйста, почему я все никак не могу получить bemhtml на клиенте вроде все ок и зависимости и все позвал. и да такой вопрос если я все пишу через bemtree (ну как bemhtml у меня чисто для тегирования и атрибутов, то есть пока там только разная мелочь) и по сути у меня нет шаблона я просто хочу использовать сам шаблонизатор на клиенте, что я делаю не так?

modules.define('manager', ['i-bem__dom', 'BEMHTML', 'menu', 'jquery'], function(provide, BEMDOM, BEMHTML, MenuEvent, $) {

    provide(BEMDOM.decl(this.name, {
        onSetMod : {
          'js' : {
            'inited' : function() {
                MenuEvent.on('update', this._taskUpd, this);
            }
          }
        },
        _taskUpd : function () {

            this.setMod(this.elem('content'), 'action', 'artAdd');

            var bemjson = {
                block: 'content',
                content: [
                ]
            };

            var html = BEMHTML.apply(bemjson);

            console.log(html);

            BEMDOM.update(this.elem('content'), html);

            return false;
        }
    }));

});

зависимости

({
  shouldDeps: [
      { elem: 'control'},
      { elem: 'content'},
      { mods: { action: 'article'} },
    { block: 'modal', mods : { theme : 'islands', autoclosable : true }},
    'button',
    'content',
    'menu',
    { block: 'i-bem', elem: 'dom' },
    { tech: 'js', mustDeps: { elem: 'content', tech: 'bemhtml' } }
  ]
})

Доброго времени суток. Подскажите пожалуйста кто знает, почему в bem-components и bem-core не используется SASS, а вместо этого все манипуляции над css совершаются с помощью JS? Чем обусловлен такой подход? Хочется очень услышать аргументы.

И небольшое пожелание по поводу ваших библиотек для BEM: запилите реализацию норм грида. Спасибо

Хочу из одного места склонировать блок в другое и потом поменять у этого клона модификатор

Если просто делать

bemDom.prepend(
    ctx,
    activeSlide.domElem
 );

то при смене модификатора у этого клона, меняется модификатор и у блока с которого происходило клонирование))

<div class="sub-menu">
        <ul class="sub-menu__list">
            <li><a class="sub-menu__link sub-menu__link_active" href="#">Главная</a></li>
            <li><a class="sub-menu__link" href="#">Мобильная версия</a></li>
            <li><a class="sub-menu__link" href="#">О компании</a></li>
            <li><a class="sub-menu__link" href="#">Каталог продукции</a></li>
            <li><a class="sub-menu__link" href="#">Склад</a></li>
            <li><a class="sub-menu__link" href="#">Партнеры</a></li>
        </ul>
        <div class="sub-menu__info">
            <div class="sub-menu__info-group">
                 адрес компании
            </div>
            <div class="sub-menu__info-group">
                 информация о компании
            </div>
        </div>
    </div>

Как именовать блоки внутри элемента? (sub-menu__info)

По ходу своей работы, часто сталкиваюсь с ajax запросами внутри i-bem блоков. Часто повторяющиеся паттерны решил вынести в отдельную надстройку над jquery.ajax.

Где можно использовать?

Допустим у вас есть кнопка, которая по клику на себя, добавляет куда то контент, а когда контента нет, удаляет сама себя

_onButtonClick: function () {
    Http
        .abortable(this)
        .get(this.params.url)
        .then(function (response) {
            BEMDOM.replace(this.domElem, response.getText());
        }.bind(this));
}

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

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

_onButtonClick: function () {
    Http
        .once(this)
        .get(this.params.url)
        .then(function (response) {
            this.showModal(response.getText());
        }.bind(this));
}

запрос на сервер отработает только единожды, последущие вызовы, этой функции, запросы на сервер делать не будут, просто буду возвращать отработанный промис.

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


this._req = Http.abortable(this);

this._req.get(this.params.someUrl).then(this._onSomeDone); //этот запрос отменится, т.к следом идет другой
this._req.get(this.params.anotherUrl).then(this._onAnotherDone);

Не нужно плодить дополнительных переменных, самому вызывать abort() у jqXHR перед другим запросом.

Или если нужно сделать два разных запроса в разные места

Http.abortable(this, 'some').get(this.params.someUrl).then(this._onSomeDone);
Http.abortable(this, 'another').get(this.params.anotherUrl).then(this._onAnotherDone);

https://github.com/JiLiZART/bem-http

Ставим через bower install bem-http, и подключаем в уровнях { path: 'libs/bem-http/common.blocks', check: false }.

Пример как использовать в блоке https://github.com/JiLiZART/bem-http/blob/master/example.blocks/app/app.js

P.S. Если есть какие либо идеи по улучшению API, буду очень благодарен.

При первом клике на кнопку, и если input пустой, то вызывается popuv рядом с input с текстом о том, что он не заполнен, но при повторной клике, popuv уже не вызывается и идут ошибки, такого рода: Uncaught TypeError: Cannot read property 'setAnchor' of null

js код:

modules.define(
    'auth',
    ['i-bem__dom', 'jquery', 'location', 'querystring'],
    function(provide, BEMDOM, $, location, qs) {

        provide(BEMDOM.decl(this.name, {
            onSetMod : {
                'js' : {
                    'inited' : function() {
                        this.__base.apply(this, arguments);
                        var _this = this;

                        this._input = this.findBlocksInside('input');

                        this.bindTo('submit', function(e) {
                            e.preventDefault();
                            _this._onSendAuth(e);
                        });
                    }
                }
            },

            _onSendAuth: function(e) {
                if (!/^([A-z0-9]{3,25})$/i.test(this._input[0].getVal())) {
                    this._dropdown = this._input[0].findBlockInside('popup');
                    this._dropdown.setAnchor(this._input[0]);
                    this._dropdown.toggleMod('visible', true);
                }
            }
        }));
    }
);

html:

<form class="auth i-bem" action="/login/auth" method="POST" data-bem="{&quot;auth&quot;:{&quot;csrf&quot;:&quot;&quot;}}">
    <div class="page-unit__login">
        <span class="input input_theme_islands input_size_m input_width_available i-bem" data-bem='{"input":{}}'><span class="input__box"><input class="input__control" placeholder="Логин"/></span>
            <div class="popup popup_target_anchor popup_autoclosable popup_theme_islands i-bem" aria-hidden="true" data-bem="{&quot;popup&quot;:{&quot;directions&quot;:[&quot;right-center&quot;]}}">Заполните поле</div>
        </span>
    </div>
    <div class="page-unit__login">
        <span class="input input_theme_islands input_size_m input_width_available i-bem" data-bem='{"input":{}}'><span class="input__box"><input class="input__control" type="password" placeholder="Пароль"/></span>
            <div class="popup popup_target_anchor popup_autoclosable popup_theme_islands i-bem" aria-hidden="true" data-bem="{&quot;popup&quot;:{&quot;directions&quot;:[&quot;right-center&quot;]}}">Заполните поле</div>
        </span>
    </div>
    <button class="button button_theme_islands button_size_m button_block_full button_type_submit button_view_action button__control i-bem" role="button" type="submit" data-bem="{&quot;button&quot;:{}}"><span class="button__text">Войти</span></button>
</form>

Подключаю bem-core.js установив через bower как описано в этом посте https://ru.bem.info/forum/469/, в консоле пишет: Uncaught ReferenceError: modules is not defined

Если подключить dev версию то ошибка на 426 строке: modules.define('cookie', function(provide) {

Доброго времени суток, при использовании bem-core появилась необходимость изменить стандартного блока page, не хотелось бы делать его дубликат, хотелось именно изменить/заменить.

хотелось бы узнать как правильно это делать

Как правильно удалять блоки? Делаю BEMDOM.destruct(...), но остаются подписки на события. В доках/коде пока решения откопать не удаётся

Хотел предложить внести bem в хаб документации devdocs https://github.com/Thibaut/devdocs

пользуюсь им из alfred, так удобнее быстро переходить к описанию методов из API

Но bem выглядит совершенно непопулярным, т.к. количество звёздочек например у https://github.com/bem/bem-core/ сильно меньше 3k У bemhtml и того меньше: https://github.com/bem/bem-xjst

Условия:

  • Source code documentations only (HTML format)
  • Project must be open source (as defined by OSI) and actively maintained
  • License must permit alteration, redistribution and commercial use
  • Project must have >3k stars on GitHub or equivalent

Кажется, с другой стороны, пользовтелей сильно больше 3k, только они не очень активны

Этот показатель хотя и является несерьёзным, всё же используется как ключевой аргумент при переходе на технологию

Может быть сделать цель, увеличить звёздочки? Замотивировать их ставить

Можно в BEM чатик написать прямо, И опосредованно в блогах и на страницах на bem.info Флешмоб на внутреннем семинаре провести + внешние конференции, тоже можно обыграть как-нибудь


Покажи настоящую популярность БЭМ, подари свою ⭐!

Доброго времени суток.

В доме имеем картину что-то типо:

<ul class="block">
    <li class="block__item">Элемент 1</li>
    <li class="block__item block__item_mod">Элемент 2</li>
    <li class="block__item">Элемент 3</li>
</ul>

Как сделать проверку наличия модификатора 'mod' у любого из элементов 'item'? Подобные вещи this.hasMod('item', 'mod') или this.hasMod(this.elem('item'), 'mod') возвращают false, все другие обращения к элементам, возвращают ошибки. Пример такой проверки нигде не могу найти, поэтому если есть какое-то место с такими примерами, буду рад за ссылку, а пока, спрашиваю здесь.

Добрый день! Начинаю осваивать БЭМ методологию и пытаюсь понять архитектуру приложения. Мне сейчас непонятны некоторые вещи:

  1. Если, в зависимости от пришедших данных, мне надо вывести два разных блока, то где мы эту логику определяем? Какая есть практика этих фронтовых контроллеров, или они не нужны вовсе?
  2. Если внутри одного блока, у меня могут быть различные другие блоки, зависящие от логики, где мне эту логику определять?
  3. Чем бандлы отличаются от БЭМ блоков в их широком представлении?

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

Есть безобразный модуль, который нельзя оставлять в покое в таком виде, помогите переделать его в БЭМ вид, а то копаю документацию, но никак не могу понять, как избавиться от jquery, всё же мозг пока не отвык от него. P.S. сейчас id объявлен через data-id="1", лишь что-бы хоть как-то реализовать работу.

Структура сейчас примерно такая:

<div class="side-panel i-bem" data-bem={"side-panel":{}}>
    <div class="side-panel__item" data-id="1">
        <div class="side-panel__action-btn">content</div>
    </div>
    <div class="side-panel__item" data-id="2">
        <div class="side-panel__action-btn">content</div>
    </div>
</div>

JS такой:

modules.define('side-panel', ['i-bem__dom', 'jquery'], function(provide, BEMDOM, $) {

provide(BEMDOM.decl(this.name,
    {
        onSetMod : {
            'js' : {
                'inited': function() {
                    var _this = this;

                    function getData() {
                        $.getJSON('json/eventsOnAir', function(data) {
                            var arrJson = data;

                            _this.elem('item').each(function() {
                                var idItem = $(this).data('id');

                                for (var i = 0; i < arrJson.length; i++){
                                    if (arrJson[i] == idItem){
                                        $(this).find('.side-panel__action-btn').addClass('side-panel__action-btn_show');
                                    } else {
                                        $(this).find('.side-panel__action-btn').removeClass('side-panel__action-btn_show');
                                    }
                                }
                            });
                        });
                    }
                    setInterval(getData, 3000);
                }
            }
        }
    }
));

});