bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Помогите разобраться с i-bem.js на конкретном примере #519

Open godfreyd opened 9 years ago

godfreyd commented 9 years ago

Всем привет! Начал разбираться с i-bem.js и возникли некоторые вопросы. В качестве тестового примера взял статью на вашем форуме https://ru.bem.info/tutorials/quick-start-static/

Создал блок с произвольным названием taskmanager, здесь код BEMJSON-блока taskmanager https://github.com/Sergei-b84/test/blob/master/1.bemjson Динамическую функциональность данного блока описал в taskmanager.js файле https://github.com/Sergei-b84/test/blob/master/taskmanager.js Файловое размещение стандартное, поэтому описывать его не стал. В общем все отработало хорошо.

Теперь я хочу усложнить структуру моего блока taskmanager и сделать ее такой https://github.com/Sergei-b84/test/blob/master/2.bemjson А вот как переписать мой taskmanager.js файл не знаю. Помогите пожалуйста. Как искать элементы, если появились вложенные дополнительные блоки, как описать эти блоки? Жду ответа. Спасибо.

tadatuta commented 9 years ago

Привет!

Есть несколько вариантов: 1) Превратить новые блоки в элементы (вместо taskmanager-header сделать taskmanager__header и аналогично для taskmanager-body'). Тогда прежный JS продолжить работать вообще без изменений. 2) Примиксовать к тем сущностям, к которым требуется доступ из блока taskmanager его элементы и обращаться к ним. В BEMJSON это может быть представлено как:

{
    block: 'input',
    mix: { block: 'taskmanager', elem: 'input' }
}

Тогда из JS блока taskmanager добраться до API инпута можно через this.findBlockInside(this.elem('input'), 'input'); // первый опциональный аргумент задает контекст поиска

3) При отправке формы в taskmanager-body генерировать событие (this.emit('submit', newValue)) и подписываться на него из taskmanager:

modules.define('taskmanager', ['i-bem__dom', 'taskmanager-body'], function(provide, BEMDOM, TaskmanagerBody) {

provide(BEMDOM.decl(this.name, {
    onSetMod: {
        js: {
            inited: function() {
                TaskmanagerBody.on(this.domElem, 'submit', function(e, data) { // подписываемся на событие submit всех блоков TaskmanagerBody в контексте текущего DOM-узла
                    console.log(data); // здесь будет переданное значение
                });
            }
        }
    }
}));

});

4) Реализовать связь между блоками с помощью https://ru.bem.info/libs/bem-core/v2/desktop/events/

5) (Плохой вариант) Искать нужные блоки с помощью цепочек findBlockInside().

godfreyd commented 9 years ago

Спасибо за ответ. Пытаюсь разобраться по предложенному Вами третьему варианту. Сделал следующее: taskmanager.js

https://github.com/Sergei-b84/test/blob/master/taskmanager.js

и taskmanager-body.js

https://github.com/Sergei-b84/test/blob/master/taskmanager-body.js

Но пока не работает (т.е. контент элемента greeting остается без изменения. ) Может у меня где-то ошибка?

P.S. Как здесь (на форуме) оформлять код? Пробовал вставлять напрямую, через

, , вставляется как текст. Не могу найти правила.

tadatuta commented 9 years ago

@Sergei-b84 здесь работает markdown в точности как на github.

godfreyd commented 9 years ago

Спасибо. Кстати в адресной строке браузера после отправки каких-то данных, они отображаются : 8080/desktop.bundles/index/index.html?task=тест+привет&select1=Courses&select2=Германия , а в самом элементе не заменяются. В чем моя ошибка?

tadatuta commented 9 years ago
diff --git a/common.blocks/taskmanager-body/taskmanager-body.js b/common.blocks/taskmanager-body/taskmanager-body.js
index 1317cc2..f6d4a9c 100644
--- a/common.blocks/taskmanager-body/taskmanager-body.js
+++ b/common.blocks/taskmanager-body/taskmanager-body.js
@@ -6,9 +6,11 @@ modules.define(
              onSetMod: { // конструктор для описания реакции на события
                  'js': {
                      'inited': function() {
+                        var input = this.findBlockInside('input');
+
                          this.bindTo('submit', function(e) { // событие, на которое будет реакция
                             e.preventDefault(); // предотвращение срабатывания события по умолчанию (отправка данных формы на сервер с перезагрузкой страницы)
-                            this.emit('submit', newValue);
+                            this.emit('submit', { task: input.getVal() });
                          });
                      }
                  }
diff --git a/common.blocks/taskmanager/taskmanager.js b/common.blocks/taskmanager/taskmanager.js
index 460b0ea..a35edd7 100644
--- a/common.blocks/taskmanager/taskmanager.js
+++ b/common.blocks/taskmanager/taskmanager.js
@@ -5,8 +5,8 @@ modules.define('taskmanager', ['i-bem__dom', 'taskmanager-body'], function(provi
                 'inited': function() {
                     TaskmanagerBody.on(this.domElem, 'submit', function(e, data) { // подписываемся на событие submit всех блоков TaskmanagerBody в контексте текущего DOM-уз
                         e.preventDefault();
-                        this.elem('greeting').text('Привет, ' + data['task'] + '!');
-                    });
+                        this.findBlockInside('taskmanager-header').elem('subtitle').text('Привет, ' + data['task'] + '!');
+                    }, this); // передаем контекст
                 }
             }
         }
tadatuta commented 9 years ago

после отправки каких-то данных, они отображаются

Предположу, что это из-за ошибки в коде просто не отрабатывает preventDefault() и форма отправляется.

godfreyd commented 9 years ago

Спасибо за ответы. Но что-то все-равно не работает. Сделал как Вы порекомендовали. также нашел Ваши ответы на похожую тему https://github.com/bem/bem-forum-content-ru/issues/393

Делал как там, все равно что-то не так. Привожу свой код на данный момент. Может у меня где ошибка?

index.bemjson.js

{
    block: 'taskmanager',
    content: [
        {
            block: 'taskmanager-header',
            content: [
                {
                    elem: 'title',
                    tag: 'h3',
                    content: 'Search Task Manager'
                },
                {
                    elem: 'subtitle',
                    tag: 'span',
                    content: 'This is subheader'
                }

            ]
        },
        {
            block: 'taskmanager-body',
            content: [
                {
                    block : 'input',
                    mods : { theme : 'islands', size : 'l', width : 'available', 'has-clear' : true },
                    mix : { block : 'taskmanager-body', elem : 'input' }, 
                    name : 'task'
                },  
                {
                    elem : 'center',
                    content: [  
                        {
                            block : 'button',
                            mods : {theme : 'islands', size : 'xl', view : 'action', type : 'submit' },
                            text : 'Search'
                        }
                    ]                       
                },                  

            ]
        }

    ]
}

taskmanager.js

modules.define('taskmanager',  ['i-bem__dom', 'taskmanager-body'], function(provide, BEMDOM,  TaskmanagerBody) {

provide(BEMDOM.decl(this.name, {
    onSetMod: {
        js: {
            inited: function() {
                TaskmanagerBody.on(this.domElem, 'submit', function(e, data) { 
                    this.findBlockInside('taskmanager-header').elem('subtitle').text('Привет, ' + data['task'] + '!');
                }); 
            }
        }
    }
}));

});

taskmanager-body.js

modules.define('taskmanager-body', // имя блока
    ['i-bem__dom'], // подключение зависимости
    function(provide, BEMDOM) { // функция, в которую передаются имена используемых модулей

provide(BEMDOM.decl('taskmanager-body', { // декларация блока
    onSetMod: { // конструктор для описания реакции на события
        'js': {
            'inited': function() {
                this._input = this.findBlockInside('input');

                this.bindTo('submit', function(e) { // событие, на которое будет реакция
                    e.preventDefault(); // предотвращение срабатывания события по умолчанию
                    this.emit('submit', newValue);
                    this.emit('submit', { 'task' : this._input.getVal() });
                });

            }
        }
    }
}));

});

taskmanager.bemhtml

block('taskmanager')(
    js()(true),
    tag()('form')
);

taskmanager-body.bemhtml

block('taskmanager-body')(
    js()(true)
);
tadatuta commented 9 years ago

Вот такие изменения решают проблему:

diff --git a/common.blocks/taskmanager-body/taskmanager-body.bemhtml b/common.blocks/taskmanager-body/taskmanager-body.bemhtml
index 04a6102..fa9355e 100644
--- a/common.blocks/taskmanager-body/taskmanager-body.bemhtml
+++ b/common.blocks/taskmanager-body/taskmanager-body.bemhtml
@@ -1,3 +1,4 @@
 block('taskmanager-body')(
-    js()(true)
+    js()(true),
+    tag()('form')
 );
diff --git a/common.blocks/taskmanager-body/taskmanager-body.js b/common.blocks/taskmanager-body/taskmanager-body.js
index 59101ec..b5ef04f 100644
--- a/common.blocks/taskmanager-body/taskmanager-body.js
+++ b/common.blocks/taskmanager-body/taskmanager-body.js
@@ -10,7 +10,6 @@ provide(BEMDOM.decl('taskmanager-body', { // декларация блока

                 this.bindTo('submit', function(e) { // событие, на которое будет реакция
                     e.preventDefault(); // предотвращение срабатывания события по умолчанию
-                    this.emit('submit', newValue);
                     this.emit('submit', { 'task' : this._input.getVal() });
                 });

diff --git a/common.blocks/taskmanager/taskmanager.bemhtml b/common.blocks/taskmanager/taskmanager.bemhtml
index 52441e1..c1f3d5f 100644
--- a/common.blocks/taskmanager/taskmanager.bemhtml
+++ b/common.blocks/taskmanager/taskmanager.bemhtml
@@ -1,4 +1,3 @@
 block('taskmanager')(
-    js()(true),
-    tag()('form')
+    js()(true)
 );
diff --git a/common.blocks/taskmanager/taskmanager.js b/common.blocks/taskmanager/taskmanager.js
index 92e664a..1aa7203 100644
--- a/common.blocks/taskmanager/taskmanager.js
+++ b/common.blocks/taskmanager/taskmanager.js
@@ -6,7 +6,7 @@ provide(BEMDOM.decl(this.name, {
             inited: function() {
                 TaskmanagerBody.on(this.domElem, 'submit', function(e, data) {
                     this.findBlockInside('taskmanager-header').elem('subtitle').text('Привет, ' + data['task'] + '!');
-                });
+                }, this);
             }
         }
     }
godfreyd commented 9 years ago

Спасибо большое за помощь, все заработало!!!