Всем привет!
Сегодня мы зарелизили bem-core@v4.0.0-rc.1.
Это релиз-кандидат большого релиза bem-core@v4.0.0, который появится совсем скоро.
Мы сделали достаточно большое количество обратно несовместимых изменений, ради того, чтобы API стало легче понять, запомнить и удобнее использовать.
Уже доступен миграционный гайд и обновлённая документация на i-bem.js
. Если вы не используете bem-components, то можно начинать изучать, крутить, вертеть и подключать к своим проектам новую версию bem-core.
Что нового и важного:
Значительно упрощено и унифицировано API работы со всеми видами событий:
this._domEvents().on('click', this._onClick); this._events(this.findChildBlock('button')).on('click', this._onButtonClick);
Кроме того, теперь все основные способы использования не требуют самостоятельного удаления подписок при уничтожении экземпляра — отписка происходит автоматически. Подробнее в миграционном гайде.
- Экземпляры для элементов перенесены в блоки
i-bem
иi-bem-dom
и стали частью ядра. Теперь с элементами работать так же удобно, как с блоками:
this.findChildElem('button').setMod('disabled');
Подробнее в миграционном гайде.
Функциональность элемента
collection
блокаi-bem
перестала быть опциональной. Все методы, возвращавшие несколько БЭМ-сущностей, теперь возвращают коллекции:this.findChildBlocks('control').setMod('disabled');
- Ленивая инициализация (поле
live
) разделена на две отдельные части — полеlazyInit
и методonInit()
. Более явные названия без смешивания в одном месте двух вещей. Подробнее в миграционном гайде. - Удалены и переименованы множество методов — API стало чище и понятнее.
Все подробности о миграции на новую версию читайте в миграционном гайде. А документация на i-bem.js
уже содержит полностью обновлённую информацию.
Мы просим вас писать нам любой фидбек о найденных ошибках и проблемах на форум или сразу в тикеты, чтобы мы могли сделать обратно несовместимые исправления до полного релиза bem-core@v4.0.0.
P. S. Релиз-кандидат bem-components с bem-core@v4 внутри будет в ближайшее время. Также мы ещё допишем английскую версию документации, чейнджлог и миграционный гайд.
this._events(this.findChildBlock('button')).on('click', this._onButtonClick);
вместоthis.findChildBlock('button').on('click', this._onButtonClick);
? В чём смысл? Только ради авто-отписки? Это не очень похоже на "значительно упрощено".Прочитал guide, всё остальное - очень нра.
Смысл в возможности автоматически отписаться при уничтожении DOM-узла родителя.
И как теперь подписываться извне? Как не-бэм-сущности подписаться на событие бэм-сущности?
Как-то странно получилось, но я упустил этот момент и присоединяюсь к вопросу ;-)
именно ради авто-отписки, т.к. сравнивать надо не просто
this._events(this.findChildBlock('button')).on('click', this._onButtonClick);
иthis.findChildBlock('button').on('click', this._onButtonClick);
, а ещё и обязательныйthis.findChildBlock('button').un('click', this._onButtonClick);
(который написан в другом месте и может быть забыт) — так что да, на мой вкус это упрощениекроме того, там много других изменений с событиями (я про них рассказывал в докладе про планы https://youtu.be/Gfd2cd5RcnU?t=14m19s)
А domElem вообще остался? Не увидел в гайде ничего про это. Если остался - давайте тоже прибъём, сбивает же с толку. К тому же блок может быть на нескольких элементах сразу, то есть можно явно показать, что это коллекция.
по поводу событий - не хотите оставить возможность подписаться на события блока напрямую, через блок + this._events для авто-отписки? Я понимаю, что "два способа подписаться получается", но на самом деле нет, способ подписаться один, _events - просто wrapper вокруг обычного api.
Ну и вопрос
пока актуален
domElem
остался, не понимаю, чем он мешает? разве что можно подумать о занесении его в приватный скоуп до_domElem
напрямую подписываться на события это как раз и есть «два способа», один из которых, к тому же, багогенный (т.к. надо не забывать отписываться) — поэтому нет, мы долго обсуждали и твёрдо решили так не делать
для подписки на события извне есть отдельный модуль
events__observable
, который предоставляет возможность создать аналогичный с_events()
ивент-менеджер от БЭМ-сущности — подробнее про использование можно посмотреть в спеках (мы не стали сходу писать про это в миграционный гайд, т.к. достаточно хардкорная тема и «нерекомендуемый путь» — «рекомендуемый» всё написать на i-bem ;-))А почему нельзя реализовать в методе
.on
автоматическую отписку всех эвент хендлеров по событию destruct. Это намного интуитивнее чем писатьthis._events.
domElem
ничем не мешает, также, как и ничем не мешаетfindBlockInside
. Просто domElem - это не domElem, а jquery коллекция.Зачем разрешать подписываться на дом-события другого блока, кстати? Мне кажется, не очень крутая тема.
@JiLiZART потому что, ситуация такова: блок A подписывается на события блока B, но делает это как
B.on(...)
, т.е. в сигнатуре подписки нет блока A и нет никакой возможности при дестракте A отписаться от этих событийв новом апи, в сигнатуре подписке участвуют оба блока (
A._events(B).on(...)
) — поэтому как раз и появляется возможность автоматически отписываться от событий@apsavin ну у нас везде написано, что под
domElem
везде подразумевается jQuery-обёртка над DOM, где читая нода, тамdomNode
— такое соглашение, т.к. чистыеdomElem
по сути и не нужны почти нигде@apsavin а мы и не разрешаем подписываться на DOM-события другого блока ;-) по крайней мере явным апи, без хаков с доставанием
domElem
events__observable_type_bem-dom
, это обёртка дляi-bem-dom
(поэтому словоdom
), а вообще там именно про БЭМ-события (ибо извне на DOM-события можно и через внешние способы подписаться)@veged ok, у нас везде было написано, что есть метод для поиска блоков "внутри" - findBlocksInside. Но его решили переименовать. Я не понимаю, в чём разница с domElem. @awinogradov помнится тоже высказывался по этому поводу.
domElem теперь с подёркивания начинается?
@apsavin были переименованы все методы поиска, в основном из-за
On
иOutside
, с которыми возникали непонимания по существуdomElem
пока не подчёркнут (подумаем), но хаки это не само обращение к нему, а дальнейшая подписка средствами jQueryЧто?) Вообще, какие-то двойные стандарты. На бэм события - "подписываемся только так и никак иначе". Ведь могут быть баги. Ведь два способа - некошерно. На дом события - можно
this._domEvents().on('click', this._onClick);
, можноthis.domElem.on('click', this._onClick);
, а можно вообщеanotherBlock.domElem.on('click', this._onClick)
. Но нет, это всё не является "багоненным" почему-то.С каких пор block.someProp.someMethod - это хак? Всё публичное, видно же, никаких
_
. Да и в доке сказано - имена протектед начинаются с_
.@apsavin я же сказал «подумаем» ;-) — видимо надо подчеркнуть
domElem
, даПодумайте заодно над переименованием в $el какой-нибудь, чтобы очевидно было, что это jquery-коллекция)
@apsavin зачем это знать? сегодня jQuery-коллекция, завтра откажемся от jQuery и будет что-то ещё — это детали реализации и тип значения мы обычно в имени не храним
А множественное/единственное число в имени отражаете? domElem - это в первую очередь коллекция, во вторую jQuery. Один блок на N узлах, все дела.
@apsavin для подавляющего большинства блоков и пользователей одного блока на нескольких узлах не существует (см. свежий пример https://web-standards.slack.com/archives/bem/p1465420743000030), поэтому множественное число в имени будет только запутывать
Для большинства - да, согласен. С моей точки зрения, это ничего не меняет. "У нас тут массив, но чаще всего в нём только один элемент и это число. Давайте просто скажем всем, что у нас тут число". Я утрирую, конечно, но ты меня должен понять. Впрочем, твоя позиция тоже понятна. Можно дальше не обсуждать.
Я в своей поделке, косящей под i-bem, (https://github.com/belozyorcev/bemby) делал "Переход в режим jQuery
.$
".Выглядело это так
Всё что было слева от
$
-BEMBy
с его методами, что правее$
- ужеjQuery
методы. Мне это давало точное визуальное понимание, что там идёт jQuery и я могу использовать все его методы.А нельзя ли вместо: this._events(this.findChildBlock('button')).on('click', this._onButtonClick);
сделать: this.on(this.findChildBlock('button'), 'click', this._onButtonClick);
@o5e2e2 так и было раньше, но вариативность параметров (полиморфичность функций) не укладывается в такую модель — см. подробнее https://github.com/bem/bem-core/blob/v4/MIGRATION.ru.md#События и https://github.com/bem/bem-core/issues/394
в цепочке
this.findChildBlock('button').on('click', this.onButtonClick);
теряется исходный thisа в реализации метода для
this.on(this.findChildBlock('button'), 'click', this.onButtonClick);
легко вызывать внутриthis._events(this.findChildBlock('button')).on('click', this._onButtonClick);
ИМХО, с точки зрения https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%94%D0%B5%D0%BC%D0%B5%D1%82%D1%80%D1%8B так API чище
@o5e2e2 если делать через
this.on(this.findChildBlock('button'), 'click', this.onButtonClick);
, то будет неудобный чейнинг с повторениемthis.findChildBlock('button')
вместо:
будет:
А так не стройнее:
BEMDOM.events(this.findChildBlock('button'), this).on('click', this.onButtonClick).on('dblclick', this.onButtonDblClick);