devextreme-vue
Version:
DevExtreme Vue UI and Visualization Components
90 lines (88 loc) • 3.41 kB
JavaScript
/*!
* devextreme-vue
* Version: 25.1.5
* Build date: Wed Sep 03 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file in the root of the project for details.
*
* https://github.com/DevExpress/devextreme-vue
*/
import domAdapter from 'devextreme/core/dom_adapter';
import { one } from 'devextreme/events';
import { discover as discoverSlots, mountTemplate, } from './templates-discovering';
import { DX_REMOVE_EVENT, DX_TEMPLATE_WRAPPER_CLASS } from './constants';
import { allKeysAreEqual } from './helpers';
class TemplatesManager {
constructor(component) {
this._slots = {};
this._templates = {};
this._isDirty = false;
this._component = component;
this.discover();
}
discover() {
this._slots = {
...discoverSlots(this._component),
};
if (!allKeysAreEqual(this._templates, this._slots)) {
this._prepareTemplates();
}
}
get templates() {
return this._templates;
}
get isDirty() {
return this._isDirty;
}
resetDirtyFlag() {
this._isDirty = false;
}
_prepareTemplates() {
this._templates = {};
for (const name of Object.keys(this._slots)) {
this._templates[name] = this.createDxTemplate(name);
}
this._isDirty = true;
}
createDxTemplate(name) {
return {
render: (data) => {
const rendered = ((onRendered, counter = 0) => () => {
if (counter === 1 && onRendered) {
onRendered();
}
counter++;
})(data.onRendered);
const scopeData = { data: data.model, index: data.index, onRendered: rendered };
const placeholder = document.createElement('div');
const container = data.container.get ? data.container.get(0) : data.container;
container.appendChild(placeholder);
const mountedTemplate = mountTemplate(() => this._slots[name], this._component, scopeData, name, placeholder);
const element = mountedTemplate.$el;
container.removeChild(placeholder);
while (placeholder.firstChild) {
container.appendChild(placeholder.firstChild);
}
domAdapter.setClass(element, DX_TEMPLATE_WRAPPER_CLASS, true);
if (element.nodeType === Node.TEXT_NODE) {
const removalListener = document.createElement(container.nodeName === 'TABLE' ? 'tbody' : 'span');
removalListener.style.display = 'none';
container.insertBefore(removalListener, container.firstChild);
one(removalListener, DX_REMOVE_EVENT, () => {
mountedTemplate.$.appContext.app.unmount.bind(mountedTemplate)();
removalListener.remove();
});
}
else {
one(element, DX_REMOVE_EVENT, mountedTemplate.$.appContext.app.unmount.bind(mountedTemplate));
}
rendered();
return element;
},
};
}
}
export { TemplatesManager };