Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Всплытие событий при удалении блока (destruct) #1417

Open
lilliputten opened this issue Sep 4, 2017 · 1 comment

Comments

@lilliputten
Copy link

lilliputten commented Sep 4, 2017

Есть примерно следующая структура вложенных блоков:

{
    block : 'box',
    mods : {
        root : true,
        id : 'layoutBox',
    },
    content : {
        block : 'box',
        mods : {
            id : 'appBox',
        },
        // Имеем некоторую вложенность блоков `box`: layoutBox->appBox->ReportLayout->Report->ReportDisplay; Т.е.:
        // ...
        content : {
            block : 'ReportDisplay',
            mix : {
                block : 'box',
                mods : {
                    id : 'ReportDisplay',
                },
            },
            content : {
                // Some content...
            },
        },
    },
}

При удалении блока ReportDisplay (при помощи BEMDOM.destruct(ReportDisplay.domElem)) по цепочке parentNode (в jquery) до верхнего уровня (layoutBox) всплывает событие на delMod('js'), в результате чего блок отписывается от событий, зарегистрированных на window (ранее подписываемся так: this._domEvents(BEMDOM.win).on('resize',...)).

Стек выглядит примерно так:

    (i-bem-dom__events.js:155) this._storage[e] = null; // e='resize' -- Это собственно удаление подписанного события в _unbindByEvent.
    // ...
    (i-bem-dom__events.js:139) objects.each(this._storage, this._unbindByEvent, this); // this._storage={resize:{uniq161:{...}}}
    (i-bem-dom__events.js:253) params.bindToArbitraryDomElem && ctxStorage[storageKey] &&
                            ctxStorage[storageKey].un();
    (i-bem-dom__events_type_bem.js:85) fn.call(fnCtx || instance, originalEvent, data); // fnCtx=null, instance=layoutBox, originalEvent={bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (jquery:5205) ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||     //  handleObj.origType='__bem__box_js_'
						handleObj.handler ).apply( matched.elem, args ); //  matched.elem=layoutBox.domElem[0], args=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:5014) jQuery.event.dispatch.apply( elem, arguments ); // elem=layoutBox.domElem[0], ...
    (jquery:8201) handle.apply( cur, data ); // cur=layoutBox.domElem[0], data=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:8262) jQuery.event.trigger(type, data, this); // type='__bem__box_js_', data=[{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}], this=ctx
    (jquery.js:8269) ctx.domElem.trigger(event, [data, { fns : {}, propagationStoppedDomNode : null }, originalEvent]); // event='__bem__box_js_', data={modName:'js',modVal:'',oldModVal:'inited'}, originalEvent:{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}
    // ...
    (i-bem-dom.js:676) bemEvents.emit(this, e, data); // e={modName:'js',modVal:''}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (i-bem-dom.js:733) this._emit({ modName : 'js', modVal : '' }, eventData); // eventData={modName:'js',modVal:'',oldModVal:'inited'}
    (i-bem.vanilla.js:324) this._afterSetMod('js', '', 'inited');
    (i-bem.vanilla.js:382) this.setMod('js', '');
    (i-bem.vanilla.js:247) this.delMod('js');
    (i-bem-dom.js:244) entity._delInitedMod();
    (i-bem-dom.js:1004) removeDomNodeFromEntity(entity, domNode);
    // ...
    (i-bem-dom.js:1029) this._destruct(ctx, excludeSelf, true);
    BEMDOM.destruct(ReportDisplay.domElem);

Полностью слепок вершины стека из DevTools, от destruct до _unbindByEvent ).

_unbindByEvent (i-bem-dom__events.js:155)
each (objects.vanilla.js:56)
un (i-bem-dom__events.js:139)
(anonymous) (i-bem-dom__events.js:254)
inherit._createEventManager (i-bem-dom__events_type_bem.js:85)
dispatch (jquery.js:5206)
jQuery.event.add.elemData.handle (jquery.js:5014)
trigger (jquery.js:8201)
(anonymous) (jquery.js:8269)
each (jquery.js:362)
each (jquery.js:157)
trigger (jquery.js:8268)
emit (i-bem-dom__events_type_bem.js:119)
_emit (i-bem-dom.js:676)
_afterSetMod (i-bem-dom.js:733)
setMod (i-bem.vanilla.js:324)
delMod (i-bem.vanilla.js:382)
_delInitedMod (i-bem.vanilla.js:247)
removeDomNodeFromEntity (i-bem-dom.js:244)
(anonymous) (i-bem-dom.js:1004)
each (objects.vanilla.js:56)
(anonymous) (i-bem-dom.js:1000)
each (jquery.js:362)
each (jquery.js:157)
_destruct (i-bem-dom.js:993)
destruct (i-bem-dom.js:1029)

Т.е., раскрутить до конца я раскрутил, но вот дальше собственных мозгов разбраться, почему так происходит, как-то уже не хватает, увы. %((

Пока обхожусь принудительной переинициализацией событий на верхнем уровне после изменения содержимого.

Хелп? Что это может быть?

Версии библиотек:

@tadatuta
Copy link
Member

tadatuta commented Sep 5, 2017

Завел задачку: bem/bem-core#1525

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants