HM-30. Добавлен класс Компонент, поправлены api, внедрен тестовый ком… (#5)

This commit is contained in:
Nikolay
2020-07-07 00:35:36 +03:00
committed by GitHub
parent 06d5ed1522
commit 6dabdd42c0
20 changed files with 580 additions and 95 deletions

View File

@ -0,0 +1,118 @@
/**
* @typedef Listener
* @type {Object}
* @property {Node} element
* @property {string} eventName
* @property {function} listener
*/
/**
* @function EventListener
* @param {unknown[]} args - аргументы функции
*/
/**
* @typedef Events
* @type {Object<string, EventListener[]>}
*/
/**
* Класс для создания компонентов приложения. Необходим для нследования.
* @class
*/
class Component {
/**
* @private
* @type {Listener[]}
*/
_listeners;
/**
* @private
* @type {Events}
*/
_events;
/**
* @public
* @type {Node} - корневой элемент компонента
*/
mainNode;
/**
* @param {string} mainNodeSelector - селектор, с помощью которого извлекается шаблон компонента
* @param {Node} parentNode - родительский Node, в который следует положить созданный элемент
*/
constructor(mainNodeSelector, parentNode) {
/**
* @type {DocumentFragment}
*/
const content = document.querySelector(mainNodeSelector).content;
if (content.children.length > 1) {
const message = '<template> должен содержать только один элемент children';
alert(message);
throw new Error(message);
}
this.mainNode = content.firstElementChild.cloneNode(true);
parentNode.appendChild(this.mainNode);
this._listeners = [];
this._events = {};
}
/**
* Метод добавления обработчиков события на Node'ы компонента
* @public
*
* @param {Node} element - элемент, на который будет навешен обработчик
* @param {string} eventName - событие, на которое будет реагировать обработчик
* @param {function} listener - обработчик события
*/
addEventListener = (element, eventName, listener) => {
element.addEventListener(eventName, listener);
this._listeners.push({element, eventName, listener});
}
/**
* Метод подписки на события компонента
* @public
*
* @param {string} eventName - событие компонента, на которое будет реагировать обработчик
* @param {EventListener} listener - обработчик события
*/
subscribe = (eventName, listener) => {
const listeners = this._events[eventName] || [];
this._events[eventName] = [
...listeners,
listener,
];
}
/**
* Метод генерирует событие
* @public
*
* @param {string} eventName - событие, которое необходимо сгенерировать
* @param {unknown[]} args - аругемнты, который необходимо передать обработчикам события
*/
next = (eventName, ...args) => {
const listeners = this._events[eventName];
listeners.forEach(listener => {
listener(...args);
});
}
/**
* Метод уничтожения компонента. Удаляет элемент из верстки, снимает обработчики и очищает подписки
* @public
*/
destroy = () => {
this._listeners.forEach(({element, eventName, listener}) => {
element.removeEventListener(eventName, listener);
});
this.mainNode.remove();
this._listeners = [];
this._events = {};
}
}
export default Component;

View File

@ -0,0 +1,3 @@
import Component from './Component';
export default Component;