Closed wKich closed 8 years ago
Причина в том, что на примиксованные блоки не применяются шаблоны.
Чтобы получить ожидаемое поведение, нужно, чтобы примиксованным был foo
:
{
block: 'textarea',
mix: { block: 'foo', js: true }
}
Всё равно возвращается undefined
. А при вызове this.elem('control')
возвращается пустой список.
А указан ли textarea
в зависимостях?
Конечно, иначе бы была ошибка can't resolve dependence
В файле foo.deps.js
прописывал:
[{
mustDeps : { block : 'i-bem', elems : 'dom' },
shouldDeps : [
{
mods : ['disabled', 'focused']
},
'control',
'textarea'
]
}]
я так понимаю, что в вызове this.elem('control')
this
указывает на foo
?
дело в том, что control
в данном случае — это элемент блока textarea
, соответственно, искать его нужно так:
this.findBlockOn('textarea').elem('control');
Я добавлял console.log(this.elem('control'))
в файл libs/bem-components/common.blocks/input/inpus.js
внутрь функции onSetMod.js.inited
Отвечает ли этот пример на вопрос: https://jsfiddle.net/tadatuta/83nmrfgy/1/ ?
Возможно для меня в виду недостаточного понимания архитектуры БЭМ компонентов кажется не совсем очевидной необходимость вызова findBlockInside
, если мы обозначили Textarea
в качестве родительского блока для foo
.
В таком случае, нам даже ненужно объявлять textarea
как родительский блок и указывать его в зависимостях и всё будет работать.
В таком случае, нам даже ненужно объявлять textarea как родительский блок и указывать его в зависимостях и всё будет работать.
Да, все так. Дело в том, что приведенный код наследует только JS-реализацию. Но чтобы она нормально отработала, нужно, чтобы у отнаследованного блока была ожидаемая разметка (в данном случае — чтобы элемент control
оказался элементом блока foo
, а не блока textarea
).
Если говорить про общую практику при использовании i-bem, то могут быть такие реальные варианты:
textarea
изменить какие-либо свойства. Тогда пользуемся уровнями переопределения и доопределяем блок под старым именем.textarea
, так и создать чуть-чуть отличающуюся. Тогда это выражается через модификатор (наследование происходит автоматически).textarea
. В этом пункте возможны несколько вариантов решения:
textarea
на своей ноде, но обладает дополнительными свойствами.textarea
лежит внутри.baseBlock
.Последний вариант используется достаточно редко. Например, в bem-components
было удобно таким образом предоставить общую функциональность для всех контролов (они все наследуются от абстрактного блока control, который предоставляет несколько универсальных методов и не обладает собственными шаблонами.
Спасибо большое за развернутый ответ. Скорее всего в моём случае будет лучше воспользоваться вторым вариантом.
Если можно, у меня есть ещё один вопрос, но касающийся BEMHTML. Я вижу в примере используется функция apply
, которая возвращает скомпилированную html разметку. Подобный пример описывается в статье "Работа с DOM-деревом", но почему-то при создании блока в проекте project-stub
вызов BEMHTML.apply()
всегда возвращает пустую строку. И если я правильно понимаю, именно так она и должна отрабатывать из-за того как объявлено в файле enb-bemxjst/techs/bemhtml.js
. Подскажите, пожалуйста, каким образом можно подключить в project-stub
работающий BEMHTML
?
На самом деле BEMHTML подключен, это вопрос про зависимости.
По умолчанию зависимости работают в режиме «технология BEMHTML блока b1 зависит от технологии BEMHTML блока b2», т.е. нужные шаблоны попадают в отдельный «серверный» бандл. Его можно подключить на клиент как обычный JS-файл и все будет работать, но зачастую это неэффективно, т.к. у нас уже есть страница с обвязкой, отрендеренная на сервере, а на клиенте нужно менять только «внутренности».
Для сборки на клиент только тех шаблонов, которые действительно нужны, используется технология depsByTech, которая позволяет выражать зависимости вида «технология JS блока b1 зависит от технологии BEMHTML блока b2».
Подробнее о том, как писать такие зависимости см. документацию: https://ru.bem.info/technology/deps/about/#Подключение-зависимостей-по-технологии
Возможно я что-то делаю не так. В
bemjson
страницы описал свой блок:Далее в
js
технологии блокаfoo
описываю декларацию:Функция инициализации блока
input
вызывается корректно, но вотthis.elem('control').val();
возвращаетundefined
.