Добрый день.
Ситуация следующая:
На форму через сокетное соединение приходит json с данными. Я преобразую его в массив и смотрю что за данные ко мне пришли. Затем в зависимости от того, что пришло идет вызов тех или иных функций. Например в данном случае, я формирую модальное окно и заполняю его данными в функции NewProcessForm(answer['data'])
, а затем вызываю его с помощью команды modal('show’)
. Модальное окно я вызываю с помощью фреймворка Bootstrap, а формирую я его согласно БЭМ.
Объясните, пожалуйста, почему вызов модального окна срабатывает только если установлен таймаут.
.ws.onmessage = function(e) {
answer = JSON.parse(e.data);
if (answer["action_name"] == "NewProcessForm") {
NewProcessForm(answer["data"]);
setTimeout(function () {
$('#place_modal_form').modal('show');
}, 1000);
}
}
function NewProcessForm(json_data){
var jdata = JSON.parse(json_data);
modules.require(['BEMHTML', 'i-bem-dom'], (BEMHTML, bemDom) => {
bemDom.append(bemDom.doc.find('#place_modal_form'), BEMHTML.apply({
tag: 'div',
cls: 'modal-dialog l-new-process',
content: [
{
tag: 'div',
cls: 'modal-content',
attrs: { 'data-form-name': 'new' },
content: [
{
tag: 'div',
cls: 'modal-body',
content: [
{
tag: 'div',
cls: 'panel panel-primary',
content: [
{
tag: 'div',
cls: 'panel-heading',
content: [
{
tag: 'button',
cls: 'close',
attrs: { type: 'button', 'data-dismiss': 'modal', 'aria-hidden': 'true' },
content: 'x'
},
{
tag: 'h3',
cls: 'panel-title modal-title',
content: 'Новая задача'
}
]
},
{
tag: 'div',
cls: 'panel-body',
content: []
},
{
tag: 'div',
cls: 'panel-footer',
content: [
{
block: 'c-button-submit',
js: true,
tag: 'button',
cls: 'btn btn-primary',
attrs: { type: 'button' },
content: [
{
elem: 'glyphicon',
tag: 'span',
cls: 'glyphicon glyphicon-ok'
},
{
elem: 'text',
tag: 'span',
content: 'Создать'
}
]
}
]
}
]
}
]
}
]
}
]
}));
});
}
Модульная система асинхронная, поэтому необходимо дождаться, пока будет предоставлены модули внутри вызова
NewProcessForm
. Решить проблему проще всего тем, чтобы показывать модальное окно прямо изнутриNewProcessForm
после обновления контента.Кстати, можно удалить все
tag: 'div'
— это значение по умолчанию, нет необходимости его писать вручную.Но вообще тут бы весь код порефакторить.
Отлично!!! Большое спасибо, за оперативность. Насчет порефакторить, это безусловно.
Подскажите еще, пожалуйста как сделать такую конструкцию:
Собственно я ни как не могу понять, как написать просто текст "Изменить". Или в рамках методологии текст не может быть вне какого ни будь блока?
Текст — это просто строка :)
Мда... все гениальное просто... Писать просто текст, я не сообразил.
Если Вы не против, то я в этой ветке еще по задаю вопросы.
Смотрите, как в такой конструкции обойтись без внешнего контента. То есть мне нужно сразу же в append добавлять результат функции. Я пробовал сразу же писать function, но тогда возникает ошибка
Как можно избежать дублирования кода. У меня в контенте подряд идут несколько одинаковых по структуре блока block: 'b-combobox-field', но с разным содержимом. Как мне не дублировать html код. Сейчас я просто копирую текст блока и вставляю ниже, а по идее я должен вызывать какой-то паттерн или шаблон. Вот моя функция:
Без content-а должно быть в точности так же, как с ним :)
BEMHTML.apply()
в качестве аргумента может принимать строку, объект или массив. Если нужно сделать какие-то вычисления, то их можно сделать либо перед вызовомBEMHTML.apply()
, сохранить в переменную результат и передать уже эту переменную, либо действительно сделать самовызывающуюся функцию, которая будет возвращать нужный результат. Это будет работать.Если бы был полный листинг вызова, я смог бы ответить, почему возникает ошибка.
По второму вопросу есть 2 варианта:
b-combobox-field
и использовать его.Спасибо, большое. По поводу вопроса без внешнего контента, я разобрался. По поводу дублирования кода, буду разбираться с BEMHTML и формировать новые вопросы :)
Добрые день. Подскажите, пожалуйста в чем разница между декларацией
modules.define('b-new-task', ['i-bem-dom'], function(provide, BEMDOM) { provide(BEMDOM.declBlock(this.name, {
и вот этой (эту я увидел вот на этом бэминаре https://www.youtube.com/watch?v=OBjKCY3TiJg)
modules.define('b-new-task', ['i-bem__dom'], function(provide, BEMDOM) { provide(BEMDOM.decl(this.name, {
Я понимаю, что в первом случае используется блок 'i-bem-dom, а во втором случае используется элемент 'i-bem__dom' библиотеки bem-core.js+bemhtml.js.
Сейчас я подписываюсь на события вот так: modules.define('b-new-task', ['i-bem-dom'], function(provide, BEMDOM) {
});
Отсюда возникает втрой вопрос, а как правильнее: this._domEvents().on('click', this._onClick); или this.bindTo('click', function() {}) Смущает, то что у меня не работает так, как описано в бэминаре (через bindTo).
@mamatkazin https://github.com/bem/bem-core/blob/v4/MIGRATION.ru.md#Изменения-в-блоке-i-bem
Большое спасибо!
Возвращаюсь к вопросу дублирования кода от 5 мая.
"#tadatuta 5 мая 2017 Написать BEMHTML-шаблон для блока b-combobox-field и использовать его."
Но ведь на выходе будет сгенерирован html код, я к сожалению не понимаю, каким образом этот код можно будет вставить в JSON структуру, которая представлена мной ранее.
Нет необходимости вставлять результат шаблонизации в JSON-структуру.
Если написать BEMHTML-шаблон для блока
b-combobox-field
, то это позволит не копипастить повторяющиеся части в BEMJSON-е, который передается на вход вBEMHTML.apply(bemjson)
.А результатом вызова
BEMHTML.apply()
в любом случае является HTML-строка, которая и вставляется в DOM-дерево. Так что здесь никаких отличий не будет.Я правильно понимаю, что в самом начале у меня нет ни какого DOM дерева. Это дерево формируется благодаря вызову вот в этой конструкции (она была описана выше)
modules.require(['BEMHTML', 'i-bem-dom'], (BEMHTML, bemDom) => { bemDom.append(bemDom.doc.find('#place_content'), BEMHTML.apply({})})
Сейчас у меня в ней идут повторяющиеся куски кода.
Я правильно понимаю, что теперь мне нужно убрать эти куски кода, а оставить вместо них пустые блоки b-combobox-field. Таким образом в результирующем DOM дереве будут пустые узлы b-combobox-field.
А заполнятся они благодаря вызову BEMHTML-шаблона. И вот дальше у меня идет "разрыв в понимании". Каким образом мне в BEMHTML-шаблоне указать, что нужно сформировать не автономную html строку, а вставить данные в результирующее дерево.
Например, я создаю BEMHTML-шаблон: var templates = bemxjst.bemhtml.compile(function() { block('header').tag()('h1'); });
Вот тут я на вход подаю bemjson, который я сформирую var html = templates.apply(bemjson);
На выходе у меня получается HTML строка.
Владимир, пожалуйста, не бросайте меня :)
@mamatkazin
Я же правильно понимаю, что речь идет о проекте на базе
project-stub
?Там все организовано таким образом, что шаблоны автоматически попадут на клиент, если указать нужные блоки в deps-файлах специальным образом:
Подробнее здесь: https://ru.bem.info/platform/deps-spec/#Поле-определяющее-технологию-реализации-БЭМ-сущности
Т.е. необходимо создать BEMHTML-файл с нужным шаблоном, прописать его в депсах и дальше звать просто
BEMHTML.apply()
.В самом шаблоне для экономии копипаста потребуется режим
content()
, а необходимые данные можно передавать через входной BEMJSON.Подробности о шаблонах тут https://ru.bem.info/platform/bem-xjst/
Не знаю насколько это отвечает на вопрос...