HM-37. Документирование классов RouteService, RoutePagesContainer. До… (#15)
This commit is contained in:
17
src/app.js
17
src/app.js
@ -13,11 +13,24 @@ navMenuButtons.render(NAV_MENU);
|
|||||||
|
|
||||||
const routerPagesContainer = new RouterPagesContainer();
|
const routerPagesContainer = new RouterPagesContainer();
|
||||||
|
|
||||||
// Новые страницы обязательно добавляем тут
|
/**
|
||||||
|
* Добавление страниц в Роутинг выполняется на странице app.js
|
||||||
|
* @example
|
||||||
|
* routerPagesContainer.addRoutes([
|
||||||
|
* {url: '/', pageComponent: MainPage},
|
||||||
|
* {url: '/api', pageComponent: ApiPage},
|
||||||
|
* ]);
|
||||||
|
*/
|
||||||
routerPagesContainer.addRoutes([
|
routerPagesContainer.addRoutes([
|
||||||
{url: '/', pageComponent: MainPage},
|
{url: '/', pageComponent: MainPage},
|
||||||
{url: '/api', pageComponent: ApiPage},
|
{url: '/api', pageComponent: ApiPage},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Этот метод генерит событие Route, чтобы все компоненты получили его после инициализации
|
/**
|
||||||
|
* Этот метод генерит событие Route, чтобы все компоненты получили его после инициализации.
|
||||||
|
* Поэтому вызывать его надо в самом конце, когда уже созданы все компоненты приложения.
|
||||||
|
* @example
|
||||||
|
* // Вызывать его можно только один раз в программе
|
||||||
|
* routeService.init();
|
||||||
|
*/
|
||||||
routeService.init();
|
routeService.init();
|
||||||
|
|||||||
@ -4,28 +4,62 @@ import NotFoundPage from '../not-found-page';
|
|||||||
|
|
||||||
import './RouterPagesContainer.css';
|
import './RouterPagesContainer.css';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface Route
|
||||||
|
* @property {string} url - маршрут страницы начинается с "/"
|
||||||
|
* @property {Component} pageComponent - компонент (класс) страницы
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для рендера страниц при изменении роутинга
|
||||||
|
*/
|
||||||
class RouterPagesContainer extends Component {
|
class RouterPagesContainer extends Component {
|
||||||
|
/**
|
||||||
|
* Список всех маршрутов
|
||||||
|
* @type {Route[]}
|
||||||
|
*/
|
||||||
routes = [];
|
routes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Текущая открытая страница
|
||||||
|
* @type {Component}
|
||||||
|
*/
|
||||||
currentPage;
|
currentPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Текущий открытый url
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
url;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
super('#page-container', document.body);
|
super('#page-container', document.body);
|
||||||
|
|
||||||
routeService.onChange(({url}) => {
|
routeService.onChange(({url}) => {
|
||||||
|
// Если под указанный url нет pageComponent, то будет испольщована страница NotFound
|
||||||
const {pageComponent: PageComponent = NotFoundPage} = this.routes.find((route) => {
|
const {pageComponent: PageComponent = NotFoundPage} = this.routes.find((route) => {
|
||||||
return route.url === url;
|
return route.url === url;
|
||||||
}) || {};
|
}) || {};
|
||||||
|
|
||||||
|
// Удаляет предыдущую страницу
|
||||||
if (this.currentPage) {
|
if (this.currentPage) {
|
||||||
this.currentPage.destroy();
|
this.currentPage.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Рендерит новую страницу, если url изменился
|
||||||
|
if (url !== this.currentUrl) {
|
||||||
|
this.currentUrl = url;
|
||||||
this.currentPage = new PageComponent('#page', this.mainNode);
|
this.currentPage = new PageComponent('#page', this.mainNode);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Добавляет страницы в компонент, чтобы рендерить их при изменении маршрута. Рекомендуется
|
||||||
|
* все страницы передавать в app.js в одном месте
|
||||||
|
* @param {Route[]} routes - список маршрутов с компонентами
|
||||||
|
*/
|
||||||
addRoutes = (routes) => {
|
addRoutes = (routes) => {
|
||||||
this.routes = this.routes.concat(routes);
|
this.routes = this.routes.concat(routes);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,11 @@ class EmitService {
|
|||||||
* Метод подписки на события компонента
|
* Метод подписки на события компонента
|
||||||
* @param {string} eventName - событие компонента, на которое будет реагировать обработчик
|
* @param {string} eventName - событие компонента, на которое будет реагировать обработчик
|
||||||
* @param {Function} listener - обработчик события
|
* @param {Function} listener - обработчик события
|
||||||
|
* @example
|
||||||
|
* // Подписка на событие
|
||||||
|
* _.subscribe('click', () => {
|
||||||
|
* ...
|
||||||
|
* });
|
||||||
*/
|
*/
|
||||||
subscribe = (eventName, listener) => {
|
subscribe = (eventName, listener) => {
|
||||||
const listeners = this._events[eventName] || [];
|
const listeners = this._events[eventName] || [];
|
||||||
@ -29,6 +34,10 @@ class EmitService {
|
|||||||
* Метод генерирует событие
|
* Метод генерирует событие
|
||||||
* @param {string} eventName - событие, которое необходимо сгенерировать
|
* @param {string} eventName - событие, которое необходимо сгенерировать
|
||||||
* @param {unknown[]} args - аругемнты, который необходимо передать обработчикам события
|
* @param {unknown[]} args - аругемнты, который необходимо передать обработчикам события
|
||||||
|
* @example
|
||||||
|
* // Сгенерировать событие. Можно передать любое количество аругментов, все эти аргументы в таком же
|
||||||
|
* // порядке будут переданы подписчикам компонента
|
||||||
|
* _.next('click', arg1, arg2, ..., argN);
|
||||||
*/
|
*/
|
||||||
next = (eventName, ...args) => {
|
next = (eventName, ...args) => {
|
||||||
const listeners = this._events[eventName];
|
const listeners = this._events[eventName];
|
||||||
|
|||||||
@ -1,9 +1,28 @@
|
|||||||
import EmitService from './EmitService';
|
import EmitService from './EmitService';
|
||||||
import {parse, stringify} from 'querystring';
|
import {parse, stringify} from 'querystring';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function RouterListener
|
||||||
|
* @param {string} url - путь роута
|
||||||
|
* @param {Object<string, string>} query - объект ключ-значение из url
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Константа для события изменения роута
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const ROUTE_CHANGE = 'routeChange';
|
const ROUTE_CHANGE = 'routeChange';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для работы с роутингом. Позволяет переходить по роутам и генерит событие изменения роута.
|
||||||
|
*/
|
||||||
class RouteService extends EmitService {
|
class RouteService extends EmitService {
|
||||||
|
/**
|
||||||
|
* @type {boolean} - проверяет чтобы инициализация была не больше одного раза
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_isInit = false;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -11,6 +30,10 @@ class RouteService extends EmitService {
|
|||||||
this._events[ROUTE_CHANGE] = [];
|
this._events[ROUTE_CHANGE] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод получения данных url'а
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
getUrlData = () => {
|
getUrlData = () => {
|
||||||
return {
|
return {
|
||||||
url: location.pathname,
|
url: location.pathname,
|
||||||
@ -18,14 +41,37 @@ class RouteService extends EmitService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерирует событие изменения роута
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
generateNext = () => {
|
generateNext = () => {
|
||||||
this.next(ROUTE_CHANGE, this.getUrlData());
|
this.next(ROUTE_CHANGE, this.getUrlData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод инициализации сервиса, чтобы сгенерить первое событие перехода для приложения
|
||||||
|
*/
|
||||||
init = () => {
|
init = () => {
|
||||||
|
if (!this._isInit) {
|
||||||
this.generateNext();
|
this.generateNext();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error('RouteService можно инициализировать только 1 раз!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод перехода по маршрутам
|
||||||
|
* @param {string} url - принимает маршрут для перехода
|
||||||
|
* @param {query} query - объект с парами ключ-значение для url
|
||||||
|
* @example
|
||||||
|
* // Переход по заданному url
|
||||||
|
* _.goTo('/users', {
|
||||||
|
* key: 'testApi',
|
||||||
|
* author: 'Petrov',
|
||||||
|
* });
|
||||||
|
* // Это создаст строку в url - site.ru/users?key=testApi&author=Petrov
|
||||||
|
*/
|
||||||
goTo = (url, query) => {
|
goTo = (url, query) => {
|
||||||
const stringQuery = stringify(query);
|
const stringQuery = stringify(query);
|
||||||
const urlWithQuery = url + (stringQuery ? `?${stringQuery}` : '');
|
const urlWithQuery = url + (stringQuery ? `?${stringQuery}` : '');
|
||||||
@ -33,6 +79,15 @@ class RouteService extends EmitService {
|
|||||||
this.generateNext();
|
this.generateNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* С помощью этого метода подписываемся на событие изменения роута.
|
||||||
|
* @param {RouterListener} listener - слушатель для события изменения роута
|
||||||
|
* @example
|
||||||
|
* // Подписка на изменение url
|
||||||
|
* _.onChange(({url, query}) => {
|
||||||
|
* ...
|
||||||
|
* });
|
||||||
|
*/
|
||||||
onChange = (listener) => {
|
onChange = (listener) => {
|
||||||
this.subscribe(ROUTE_CHANGE, listener);
|
this.subscribe(ROUTE_CHANGE, listener);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user