You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/bg/7-bank-project/1-template-route/README.md

23 KiB

Създаване на Банкова Приложение Част 1: HTML Шаблони и Роутове в Уеб Приложение

Предварителен Тест

Предварителен тест

Въведение

С появата на JavaScript в браузърите, уебсайтовете стават все по-интерактивни и сложни. Уеб технологиите вече често се използват за създаване на напълно функционални приложения, които работят директно в браузъра и които наричаме уеб приложения. Тъй като уеб приложенията са силно интерактивни, потребителите не искат да чакат пълно презареждане на страницата всеки път, когато се извършва действие. Затова JavaScript се използва за директно обновяване на HTML чрез DOM, за да се осигури по-гладко потребителско изживяване.

В този урок ще положим основите за създаване на банково уеб приложение, използвайки HTML шаблони за създаване на множество екрани, които могат да се показват и обновяват без необходимост от презареждане на цялата HTML страница.

Предварителни изисквания

Ще ви е необходим локален уеб сървър, за да тествате уеб приложението, което ще създадем в този урок. Ако нямате такъв, можете да инсталирате Node.js и да използвате командата npx lite-server от папката на вашия проект. Това ще създаде локален уеб сървър и ще отвори приложението ви в браузър.

Подготовка

На вашия компютър създайте папка с име bank и файл с име index.html вътре в нея. Ще започнем с този HTML шаблон:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

HTML шаблони

Ако искате да създадете множество екрани за уеб страница, едно решение би било да създадете отделен HTML файл за всеки екран, който искате да покажете. Въпреки това, това решение има някои неудобства:

  • Трябва да презареждате целия HTML при смяна на екрана, което може да бъде бавно.
  • Трудно е да се споделят данни между различните екрани.

Друг подход е да имате само един HTML файл и да дефинирате множество HTML шаблони, използвайки елемента <template>. Шаблонът е многократно използваем HTML блок, който не се показва от браузъра и трябва да бъде инстанциран по време на изпълнение с помощта на JavaScript.

Задача

Ще създадем банково приложение с два екрана: страницата за вход и таблото за управление. Първо, нека добавим в HTML тялото елемент за запазване на място, който ще използваме за инстанциране на различните екрани на нашето приложение:

<div id="app">Loading...</div>

Даваме му id, за да го намираме по-лесно с JavaScript по-късно.

Съвет: тъй като съдържанието на този елемент ще бъде заменено, можем да поставим съобщение за зареждане или индикатор, който ще се показва, докато приложението се зарежда.

След това, нека добавим HTML шаблон за страницата за вход. Засега ще поставим само заглавие и секция, съдържаща връзка, която ще използваме за навигация.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

След това ще добавим друг HTML шаблон за страницата на таблото за управление. Тази страница ще съдържа различни секции:

  • Заглавие с текст и връзка за изход
  • Текущият баланс на банковата сметка
  • Списък с транзакции, показан в таблица
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

Съвет: когато създавате HTML шаблони, ако искате да видите как ще изглеждат, можете да коментирате линиите <template> и </template>, като ги оградите с <!-- -->.

Защо мислите, че използваме id атрибути за шаблоните? Можем ли да използваме нещо друго, като класове?

Показване на шаблони с JavaScript

Ако опитате текущия HTML файл в браузър, ще видите, че той остава на Loading.... Това е така, защото трябва да добавим JavaScript код, за да инстанцираме и покажем HTML шаблоните.

Инстанцирането на шаблон обикновено се извършва в 3 стъпки:

  1. Извличане на елемента шаблон в DOM, например с document.getElementById.
  2. Клониране на елемента шаблон, използвайки cloneNode.
  3. Прикачване към DOM под видим елемент, например с appendChild.

Защо трябва да клонираме шаблона, преди да го прикачим към DOM? Какво мислите, че би се случило, ако пропуснем тази стъпка?

Задача

Създайте нов файл с име app.js в папката на вашия проект и го импортирайте в секцията <head> на вашия HTML:

<script src="app.js" defer></script>

Сега в app.js ще създадем нова функция updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Това, което правим тук, са точно 3-те стъпки, описани по-горе. Инстанцираме шаблона с id templateId и поставяме неговото клонирано съдържание в нашия елемент за запазване на място. Забележете, че трябва да използваме cloneNode(true), за да копираме цялото поддърво на шаблона.

Сега извикайте тази функция с един от шаблоните и вижте резултата.

updateRoute('login');

Каква е целта на този код app.innerHTML = '';? Какво се случва без него?

Създаване на роутове

Когато говорим за уеб приложение, наричаме Роутинг намерението да се свържат URL адреси със специфични екрани, които трябва да бъдат показани. На уебсайт с множество HTML файлове това се прави автоматично, тъй като пътищата на файловете се отразяват в URL адреса. Например, с тези файлове в папката на вашия проект:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

Ако създадете уеб сървър с mywebsite като корен, картографирането на URL адресите ще бъде:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

Въпреки това, за нашето уеб приложение използваме един HTML файл, съдържащ всички екрани, така че това стандартно поведение няма да ни помогне. Трябва да създадем тази карта ръчно и да обновим показания шаблон с помощта на JavaScript.

Задача

Ще използваме прост обект, за да реализираме карта между URL пътища и нашите шаблони. Добавете този обект в началото на вашия app.js файл.

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

Сега нека модифицираме малко функцията updateRoute. Вместо директно да подаваме templateId като аргумент, искаме да го извлечем, като първо погледнем текущия URL адрес, а след това използваме нашата карта, за да получим съответната стойност на templateId. Можем да използваме window.location.pathname, за да получим само секцията с пътя от URL адреса.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Тук картографирахме декларираните роутове към съответния шаблон. Можете да проверите дали работи правилно, като промените URL адреса ръчно в браузъра.

Какво се случва, ако въведете неизвестен път в URL адреса? Как бихме могли да решим този проблем?

Добавяне на навигация

Следващата стъпка за нашето приложение е да добавим възможност за навигация между страниците, без да се налага ръчно да променяме URL адреса. Това включва две неща:

  1. Обновяване на текущия URL адрес
  2. Обновяване на показания шаблон въз основа на новия URL адрес

Вече се погрижихме за втората част с функцията updateRoute, така че трябва да разберем как да обновим текущия URL адрес.

Ще трябва да използваме JavaScript и по-специално history.pushState, който позволява обновяване на URL адреса и създаване на нов запис в историята на браузъра, без да се презарежда HTML.

Забележка: Докато HTML елементът за връзка <a href> може да се използва самостоятелно за създаване на хипервръзки към различни URL адреси, той ще накара браузъра да презареди HTML по подразбиране. Необходимо е да се предотврати това поведение при обработка на роутинг с персонализиран JavaScript, използвайки функцията preventDefault() върху събитието за клик.

Задача

Нека създадем нова функция, която можем да използваме за навигация в нашето приложение:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

Този метод първо обновява текущия URL адрес въз основа на дадения път, след това обновява шаблона. Свойството window.location.origin връща корена на URL адреса, което ни позволява да реконструираме пълен URL адрес от даден път.

Сега, когато имаме тази функция, можем да се погрижим за проблема, който имаме, ако пътят не съответства на някой от дефинираните роутове. Ще модифицираме функцията updateRoute, като добавим резервен вариант към един от съществуващите роутове, ако не можем да намерим съвпадение.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  ...

Ако роут не може да бъде намерен, сега ще пренасочим към страницата за вход.

Сега нека създадем функция за получаване на URL адреса, когато се кликне върху връзка, и за предотвратяване на стандартното поведение на браузъра за връзки:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

Нека завършим системата за навигация, като добавим връзки към нашите Login и Logout линкове в HTML.

<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

Обектът event по-горе улавя събитието click и го предава на нашата функция onLinkClick.

Използвайки атрибута onclick, свържете събитието click с JavaScript код, тук извикването на функцията navigate().

Опитайте да кликнете върху тези връзки, сега трябва да можете да навигирате между различните екрани на вашето приложение.

Методът history.pushState е част от стандарта HTML5 и е имплементиран във всички модерни браузъри. Ако създавате уеб приложение за по-стари браузъри, има трик, който можете да използвате вместо този API: използвайки хаш (#) преди пътя, можете да реализирате роутинг, който работи с обикновена навигация чрез връзки и не презарежда страницата, тъй като целта му е да създава вътрешни връзки в рамките на страница.

Обработка на бутоните за назад и напред в браузъра

Използването на history.pushState създава нови записи в историята на навигацията на браузъра. Можете да проверите това, като задържите бутона за назад на браузъра си, той трябва да показва нещо подобно:

Снимка на историята на навигацията

Ако опитате да кликнете върху бутона за назад няколко пъти, ще видите, че текущият URL адрес се променя и историята се обновява, но същият шаблон продължава да се показва.

Това е така, защото приложението не знае, че трябва да извика updateRoute() всеки път, когато историята се промени. Ако погледнете документацията за history.pushState, можете да видите, че ако състоянието се промени - което означава, че сме преминали към различен URL адрес - събитието popstate се задейства. Ще използваме това, за да поправим този проблем.

Задача

За да се уверим, че показаният шаблон се обновява, когато историята на браузъра се промени, ще прикачим нова функция, която извиква updateRoute(). Ще направим това в края на нашия app.js файл:

window.onpopstate = () => updateRoute();
updateRoute();

Забележка: използвахме стрелкова функция, за да декларираме нашия обработчик на събитие popstate за краткост, но обикновена функция би работила по същия начин.

Ето видео за освежаване на знанията за стрелкови функции:

Стрелкови функции

🎥 Кликнете върху изображението по-горе за видео за стрелкови функции.

Сега опитайте да използвате бутоните за назад и напред на браузъра си и проверете дали показаният роут се обновява правилно този път.


🚀 Предизвикателство

Добавете нов шаблон и роут за трета страница, която показва кредитите за това приложение.

Тест след урока

Тест след урока

Преглед и Самостоятелно Обучение

Роутингът е една от изненадващо сложните части на уеб разработката, особено когато уебът преминава от поведения с презареждане на страници към приложения с еднократна страница. Прочетете малко за как услугата Azure Static Web App обработва роутинг. Можете ли да обясните защо някои от решенията, описани в този документ, са необходими?

Задание

Подобрете роутинга


Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.