Привет.
Я тут думаю, как бы мне так доопределить bemtree, чтобы можно было писать
block('block').js()({a: 1});
и
block('block')(
js()({a: 1})
);
вместо
block('block').def()(function () {
this.ctx.js = {a: 1};
return applyNext(this.ctx);
});
Может, кто-то уже делал такое?
Вот этот applyAsync не тот же механизм, который ты ищешь?
нет.
Тогда я бы копал отсюда
Решил задачу, добавив на своем уровне переопределения:
Может кто-нибудь прокомментировать, насколько это плохо? Почему бы это не включить в bemtree?
:+1: Насколько я понимаю ситуацию, то если и включать, то в
bem-core/i-bem.bemtree
, я лично за, выглядит очень логично. Наверное, надо позвать @veged и @mishanga@apsavin я не понимаю зачем ты хочешь в шаблоне bemtree для конкретного по моде записывать в js что-то? Мне кажется ты хочешь не правильного.
У тебя же всегда есть какой нибудь блок page.bemtree в котором ты описываешь бэмдерево вот там самое место что бы в bemjson для внутренних блоков описать все что ты хочешь передать в js. Надеюсь я понятно написал)
@voischev я хочу, чтобы блок сам ходил за данными, которые ему нужны.
@apsavin не знаю какая у тебя специфика, но у нас такой подход не очень прижился, потому что получается очень много лишних преобразований и дублирований. В наших проектах удобнее формировать дерево страницы из одного места, ну и соответственно прикидывать нужные данные в блоки из этого же места). У нас одни и те же блоки могут принимать структурно похожие данные из разных мест и кажется очень сложно будет накрутить такую логику внутри блока, который по сути должен будет знать про все приложение, или все возможные варианты использования этого блока, вместо того что бы просто принимать данные и что-то с ними делать внутри.
@voischev у меня есть ощущение, что должно быть два класса блоков: страничные, и обычные. И у страничных можно кроме bemtree, с общей канвой внутренней структуры, описать еще и нодовую технологию, которая будет за данными бегать, а в обычных блоках только bemtree при необходимости, ну или, если блок прям совсем независимый, тоже можно нодовую реализацию. Таким образом у нас получается куча разных типов страниц, описанных страничными блоками, которые знают примерно что в них напихано, и знают чем это рисовать, а дальше логика всем известная: bemtree→bemjson→bemhtml.
upd: т.е., рутовых блоков для bemtree может быть не один, а пачка. А какой из них нужный для конкретной страницы — решится при запуске нодовой технологии. У нас такой подход (на php аналоге node+bemtree) идеально ложится под CMS и нужды.
Я не спорю. Но мне думается что таких блоков не должно быть много :) рутовый блок по дефолтной ноде обычно вернет другой контекст с другим блоком. Вот и для решения этой задачи я бы сделал блок без представления который бы готовил данные для блока который нужно отобразить. Будет выглядить гораздо красивее ;)
// cc @narqo
@apsavin Если я правильно понимаю, то достаточно на своем уровне положить
PS: Для твоей задачи, когда каждый блок ходит за своими данными, обрати внимание на https://github.com/baby-loris/bla — модуль как раз для этого.
@tadatuta То, что ты предлагаешь - это то, с чего я начал, в такой записи apply('js') ничего не возвращает, помогает только редактирование i-bem.bemtree в bem-core так, как я написал выше. Но, может быть, я где-то ошибся, попробую еще раз.
Спасибо за рекомендацию
bla
, но у меня уже свой велосипед, который делает примерно тоже самое, но более удобным для меня образом.@tadatuta Я вчера пытался найти в доке, в тестах что-то похожее, но так и не понял, как это сделать, пока не увидел этих четырех строчек. А кейс, по ощущениям, частый.
Есть же еще вариант реализовывать это через
mode('custom-mode')(...)
, верно? Чем он хуже «стандартных» мод типаjs
? Почему нельзя доопределить стандартные моды на базовом уровне (или все же можно)? (Имеется ввиду, определение некоеговоaria
, например, с последующим использованиемaria('flowto')(...);
)Ощущение, что написано про это много, всё в примерах, но что-то важное упущено.
@apsavin
apply('js')
не будет ничего возвращать для случаев, когда на него не написаны шаблонынадо или добавить к коду @tadatuta
или делать примерно как в твоём изначальном коде:
в базовые шаблоны не хочется это выносить, т.к. обычно всё можно сделать в моде
def
@zxqfox любые моды до- и переопределяются совершенно консистентно, хоть базовые, хоть кастомные. и в этом плане пример про доопределение моды
content
с вызовомapplyNext()
ничем не отличается от аналогичного доопределения дефолтной моды@tadatuta Вот это как раз и неочевидно. Пример такого рода был бы весьма кстати.
@veged @tadatuta Странно, но предложенные вами варианты не работают. А вот если мой вариант разместить на уровне проекта в i-bem.bemtree - то все ок. Не работают - это значит то, что я передаю в js, игнорируется.
@veged
apply('js')
всегда возвращает undefined в случае использованияи вызывается явно меньшее количество раз. Собственно, видимо, просто не вызывается для того случая, когда я его использую.
@apsavin я взял
project-stub@bem-core
, сделал https://github.com/bem/project-stub/compare/bemtreeJsMode?expand=1 (т.е. ровно такой шаблон, как в твоем комменте, без отдельного объявления модыjs
, как рекомендует @veged ) и в результате получаю:Чтобы повторить:
@tadatuta
Не может ли быть дело в
???
@apsavin для dev-режима лечится так:
Да, но если использовать дерево
то с моим кодом результат:
а с вашим:
@apsavin, действительно,
applyNext()
выставляет защиту от зацикливания в виде поля вthis
. И т.к.this
общий для всех потомков, то вглубь по дереву шаблон больше не матчится.Угу, видимо, придется оставить мой вариант, с некоторым дублированием кода из i-bem.bemtree в bem-core