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