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/lt/7-bank-project/3-data
Lee Stott 2daab5271b
Update Quiz Link
3 weeks ago
..
README.md Update Quiz Link 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 3 weeks ago

README.md

Sukurkite bankinę programėlę 3 dalis: Duomenų gavimo ir naudojimo metodai

Klausimynas prieš paskaitą

Klausimynas prieš paskaitą

Įvadas

Kiekvienos internetinės programėlės pagrindas yra duomenys. Duomenys gali būti įvairių formų, tačiau jų pagrindinis tikslas visada yra pateikti informaciją vartotojui. Kadangi internetinės programėlės tampa vis interaktyvesnės ir sudėtingesnės, tai, kaip vartotojas pasiekia ir sąveikauja su informacija, tampa esmine interneto kūrimo dalimi.

Šioje pamokoje pamatysime, kaip asinchroniškai gauti duomenis iš serverio ir naudoti juos informacijai pateikti interneto puslapyje, neperkraunant HTML.

Būtinos sąlygos

Jums reikia būti sukūrus Prisijungimo ir registracijos formą kaip šios pamokos dalį. Taip pat turite įdiegti Node.js ir paleisti serverio API lokaliai, kad gautumėte paskyros duomenis.

Galite patikrinti, ar serveris veikia tinkamai, vykdydami šią komandą terminale:

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

AJAX ir duomenų gavimas

Tradicinės interneto svetainės atnaujina rodomą turinį, kai vartotojas pasirenka nuorodą arba pateikia duomenis naudodamas formą, perkraudamos visą HTML puslapį. Kiekvieną kartą, kai reikia įkelti naujus duomenis, interneto serveris grąžina visiškai naują HTML puslapį, kurį naršyklė turi apdoroti, nutraukdama dabartinį vartotojo veiksmą ir apribodama sąveiką per įkrovimą. Šis darbo procesas taip pat vadinamas daugiapuslapių programėlių arba MPA.

Atnaujinimo procesas daugiapuslapių programėlėje

Kai internetinės programėlės pradėjo tapti sudėtingesnės ir interaktyvesnės, atsirado nauja technika, vadinama AJAX (Asynchronous JavaScript and XML). Ši technika leidžia internetinėms programėlėms siųsti ir gauti duomenis iš serverio asinchroniškai naudojant JavaScript, neperkraunant HTML puslapio, todėl atnaujinimai vyksta greičiau, o vartotojo sąveika tampa sklandesnė. Kai nauji duomenys gaunami iš serverio, dabartinis HTML puslapis taip pat gali būti atnaujintas naudojant DOM API. Laikui bėgant, šis požiūris išsivystė į tai, kas dabar vadinama vieno puslapio programėle arba SPA.

Atnaujinimo procesas vieno puslapio programėlėje

Kai AJAX buvo pirmą kartą pristatytas, vienintelė API, leidžianti asinchroniškai gauti duomenis, buvo XMLHttpRequest. Tačiau šiuolaikinės naršyklės dabar taip pat įgyvendina patogesnę ir galingesnę Fetch API, kuri naudoja pažadus ir yra geriau pritaikyta manipuliuoti JSON duomenimis.

Nors visos šiuolaikinės naršyklės palaiko Fetch API, jei norite, kad jūsų internetinė programėlė veiktų senesnėse naršyklėse, visada verta patikrinti suderinamumo lentelę caniuse.com.

Užduotis

Ankstesnėje pamokoje įgyvendinome registracijos formą paskyrai sukurti. Dabar pridėsime kodą, kad galėtume prisijungti naudojant esamą paskyrą ir gauti jos duomenis. Atidarykite app.js failą ir pridėkite naują login funkciją:

async function login() {
  const loginForm = document.getElementById('loginForm')
  const user = loginForm.user.value;
}

Čia pradedame nuo formos elemento gavimo naudojant getElementById(), o tada gauname vartotojo vardą iš įvesties su loginForm.user.value. Kiekvieną formos valdiklį galima pasiekti pagal jo pavadinimą (nustatytą HTML naudojant name atributą) kaip formos savybę.

Panašiai kaip darėme registracijai, sukursime kitą funkciją, skirtą serverio užklausai atlikti, tačiau šį kartą duomenims gauti:

async function getAccount(user) {
  try {
    const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user));
    return await response.json();
  } catch (error) {
    return { error: error.message || 'Unknown error' };
  }
}

Naudojame fetch API, kad asinchroniškai užklaustume duomenis iš serverio, tačiau šį kartą mums nereikia jokių papildomų parametrų, išskyrus URL, kurį reikia iškviesti, nes mes tik užklausome duomenis. Pagal numatymą fetch sukuria GET HTTP užklausą, kurios mes čia siekiame.

encodeURIComponent() yra funkcija, kuri užkoduoja specialius simbolius URL. Kokias problemas galėtume turėti, jei nekviestume šios funkcijos ir tiesiogiai naudotume user reikšmę URL?

Dabar atnaujinkime mūsų login funkciją, kad ji naudotų getAccount:

async function login() {
  const loginForm = document.getElementById('loginForm')
  const user = loginForm.user.value;
  const data = await getAccount(user);

  if (data.error) {
    return console.log('loginError', data.error);
  }

  account = data;
  navigate('/dashboard');
}

Pirma, kadangi getAccount yra asinchroninė funkcija, turime ją suderinti su await raktažodžiu, kad lauktume serverio rezultato. Kaip ir bet kurioje serverio užklausoje, taip pat turime spręsti klaidų atvejus. Kol kas pridėsime tik žurnalo pranešimą, kad būtų rodoma klaida, ir vėliau grįšime prie jos.

Tada turime išsaugoti duomenis kažkur, kad vėliau galėtume juos naudoti informacijos pateikimui prietaisų skydelyje. Kadangi account kintamasis dar neegzistuoja, sukursime globalų kintamąjį failo viršuje:

let account = null;

Kai vartotojo duomenys išsaugomi kintamajame, galime pereiti nuo prisijungimo puslapio prie prietaisų skydelio naudodami jau turimą navigate() funkciją.

Galiausiai, turime iškviesti mūsų login funkciją, kai prisijungimo forma pateikiama, modifikuodami HTML:

<form id="loginForm" action="javascript:login()">

Patikrinkite, ar viskas veikia tinkamai, registruodami naują paskyrą ir bandydami prisijungti naudodami tą pačią paskyrą.

Prieš pereidami prie kitos dalies, taip pat galime užbaigti register funkciją, pridėdami tai funkcijos apačioje:

account = result;
navigate('/dashboard');

Ar žinojote, kad pagal numatymą serverio API galite kviesti tik iš to paties domeno ir prievado, kaip ir interneto puslapis, kurį peržiūrite? Tai yra naršyklių taikoma saugumo priemonė. Bet palaukite, mūsų internetinė programėlė veikia localhost:3000, o serverio API veikia localhost:5000, kodėl tai veikia? Naudojant techniką, vadinamą Cross-Origin Resource Sharing (CORS), galima atlikti kryžminės kilmės HTTP užklausas, jei serveris prideda specialias antraštes prie atsakymo, leidžiančias išimtis konkretiems domenams.

Sužinokite daugiau apie API, peržiūrėdami šią pamoką

Atnaujinkite HTML, kad būtų rodomi duomenys

Dabar, kai turime vartotojo duomenis, turime atnaujinti esamą HTML, kad juos būtų galima rodyti. Jau žinome, kaip gauti elementą iš DOM, pavyzdžiui, naudojant document.getElementById(). Kai turite bazinį elementą, čia yra keletas API, kurias galite naudoti norėdami jį modifikuoti arba pridėti vaikų elementų:

  • Naudojant textContent savybę galite pakeisti elemento tekstą. Atkreipkite dėmesį, kad keičiant šią reikšmę pašalinami visi elemento vaikai (jei jų yra) ir pakeičiama pateiktu tekstu. Todėl tai taip pat yra efektyvus būdas pašalinti visus nurodyto elemento vaikus, priskiriant tuščią eilutę ''.

  • Naudojant document.createElement() kartu su append() metodu galite sukurti ir pridėti vieną ar daugiau naujų vaikų elementų.

Naudojant innerHTML savybę elemento HTML turinį taip pat galima pakeisti, tačiau šios savybės reikėtų vengti, nes ji yra pažeidžiama kryžminio svetainės scenarijaus (XSS) atakoms.

Užduotis

Prieš pereidami prie prietaisų skydelio ekrano, turime atlikti dar vieną dalyką prisijungimo puslapyje. Šiuo metu, jei bandote prisijungti su vartotojo vardu, kuris neegzistuoja, pranešimas rodomas konsolėje, tačiau paprastam vartotojui niekas nesikeičia ir nežinote, kas vyksta.

Pridėkime vietos rezervavimo elementą prisijungimo formoje, kur prireikus galime rodyti klaidos pranešimą. Geriausia vieta būtų prieš prisijungimo <button>:

...
<div id="loginError"></div>
<button>Login</button>
...

Šis <div> elementas yra tuščias, tai reiškia, kad nieko nebus rodoma ekrane, kol nepridėsime turinio. Taip pat suteikiame jam id, kad galėtume lengvai jį gauti naudodami JavaScript.

Grįžkite į app.js failą ir sukurkite naują pagalbinę funkciją updateElement:

function updateElement(id, text) {
  const element = document.getElementById(id);
  element.textContent = text;
}

Ši funkcija yra gana paprasta: pateikus elemento id ir tekstą, ji atnaujins DOM elemento tekstinį turinį, atitinkantį id. Naudokime šį metodą vietoje ankstesnio klaidos pranešimo login funkcijoje:

if (data.error) {
  return updateElement('loginError', data.error);
}

Dabar, jei bandysite prisijungti su neteisinga paskyra, turėtumėte matyti kažką panašaus:

Ekrano nuotrauka, rodanti klaidos pranešimą prisijungimo metu

Dabar turime klaidos tekstą, kuris vizualiai rodomas, tačiau jei bandysite jį naudoti su ekrano skaitytuvu, pastebėsite, kad nieko nepranešama. Kad tekstas, kuris dinamiškai pridedamas prie puslapio, būtų pranešamas ekrano skaitytuvams, jis turės naudoti vadinamąją Live Region. Čia naudosime specifinį gyvos srities tipą, vadinamą pranešimu:

<div id="loginError" role="alert"></div>

Įgyvendinkite tą patį elgesį register funkcijos klaidoms (nepamirškite atnaujinti HTML).

Informacijos rodymas prietaisų skydelyje

Naudodami tuos pačius metodus, kuriuos ką tik matėme, taip pat pasirūpinsime paskyros informacijos rodymu prietaisų skydelio puslapyje.

Štai kaip atrodo paskyros objektas, gautas iš serverio:

{
  "user": "test",
  "currency": "$",
  "description": "Test account",
  "balance": 75,
  "transactions": [
    { "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
    { "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
    { "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
  ],
}

Pastaba: kad būtų lengviau, galite naudoti iš anksto sukurtą test paskyrą, kuri jau yra užpildyta duomenimis.

Užduotis

Pradėkime nuo "Balanso" skyriaus pakeitimo HTML, kad pridėtume vietos rezervavimo elementus:

<section>
  Balance: <span id="balance"></span><span id="currency"></span>
</section>

Taip pat pridėsime naują skyrių žemiau, kad būtų rodoma paskyros aprašymas:

<h2 id="description"></h2>

Kadangi paskyros aprašymas veikia kaip turinio antraštė, jis semantiškai pažymėtas kaip antraštė. Sužinokite daugiau apie tai, kaip antraščių struktūra yra svarbi prieinamumui, ir kritiškai įvertinkite puslapį, kad nustatytumėte, kas dar galėtų būti antraštė.

Tada sukursime naują funkciją app.js, kad užpildytume vietos rezervavimo elementus:

function updateDashboard() {
  if (!account) {
    return navigate('/login');
  }

  updateElement('description', account.description);
  updateElement('balance', account.balance.toFixed(2));
  updateElement('currency', account.currency);
}

Pirma, patikriname, ar turime reikalingus paskyros duomenis, prieš tęsdami. Tada naudojame anksčiau sukurtą updateElement() funkciją, kad atnaujintume HTML.

Kad balanso rodymas būtų gražesnis, naudojame metodą toFixed(2), kad priverstinai rodytume reikšmę su 2 skaitmenimis po kablelio.

Dabar turime iškviesti mūsų updateDashboard() funkciją kiekvieną kartą, kai prietaisų skydelis įkeliamas. Jei jau baigėte 1 pamokos užduotį, tai turėtų būti paprasta, kitaip galite naudoti šią įgyvendinimą.

Pridėkite šį kodą updateRoute() funkcijos pabaigoje:

if (typeof route.init === 'function') {
  route.init();
}

Ir atnaujinkite maršrutų apibrėžimą su:

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

Su šiuo pakeitimu kiekvieną kartą, kai rodomas prietaisų skydelio puslapis, iškviečiama funkcija updateDashboard(). Po prisijungimo turėtumėte matyti paskyros balansą, valiutą ir aprašymą.

Dinamiškai kurkite lentelės eilutes naudodami HTML šablonus

Pirmoje pamokoje](../1-template-route/README.md) naudojome HTML šablonus kartu su appendChild() metodu, kad įgyvendintume navigaciją mūsų programėlėje. Šablonai taip pat gali būti mažesni ir naudojami dinamiškai užpildyti pasikartojančias puslapio dalis.

Naudosime panašų požiūrį, kad rodytume operacijų sąrašą HTML lentelėje.

Užduotis

Pridėkite naują šabloną HTML <body>:

<template id="transaction">
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</template>

Šis šablonas atspindi vieną lentelės eilutę su 3 stulpeliais, kuriuos norime užpildyti: data, objektas ir suma operacijos.

Tada pridėkite šį id atributą <tbody> elementui lentelėje prietaisų skydelio šablone, kad būtų lengviau rasti naudojant JavaScript:

<tbody id="transactions"></tbody>

Mūsų HTML paruoštas, pereikime prie JavaScript kodo ir sukurkime naują funkciją createTransactionRow:

function createTransactionRow(transaction) {
  const template = document.getElementById('transaction');
  const transactionRow = template.content.cloneNode(true);
  const tr = transactionRow.querySelector('tr');
  tr.children[0].textContent = transaction.date;
  tr.children[1].textContent = transaction.object;
  tr.children[2].textContent = transaction.amount.toFixed(2);
  return transactionRow;
}

Ši funkcija daro būtent tai, ką jos pavadinimas reiškia: naudodama anksčiau sukurtą šabloną, ji sukuria naują lentelės eilutę ir užpildo jos turinį naudodama operacijos duomenis. Naudosime tai mūsų updateDashboard() funkcijoje, kad užpildytume lentelę:

const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
  const transactionRow = createTransactionRow(transaction);
  transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);

Čia naudojame metodą document.createDocumentFragment(), kuris sukuria naują DOM fragmentą, su kuriuo galime dirbti, prieš galiausiai jį prijungdami prie mūsų HTML lentelės.

Dar yra vienas dalykas, kurį turime padaryti, kad šis kodas veiktų, nes mūsų updateElement() funkcija šiuo metu palaiko tik Jei bandysite prisijungti naudodami paskyrą „test“, dabar turėtumėte matyti operacijų sąrašą prietaisų skydelyje 🎉.


🚀 Iššūkis

Dirbkite kartu, kad prietaisų skydelio puslapis atrodytų kaip tikra bankininkystės programa. Jei jau stilizavote savo programą, pabandykite naudoti media užklausas, kad sukurtumėte prisitaikantį dizainą, kuris gerai veiktų tiek staliniuose, tiek mobiliuosiuose įrenginiuose.

Štai pavyzdys, kaip gali atrodyti stilizuotas prietaisų skydelio puslapis:

Stilizuoto prietaisų skydelio pavyzdžio ekrano nuotrauka

Po paskaitos testas

Po paskaitos testas

Užduotis

Refaktorizuokite ir pakomentuokite savo kodą


Atsakomybės apribojimas:
Šis dokumentas buvo išverstas naudojant AI vertimo paslaugą Co-op Translator. Nors siekiame tikslumo, atkreipkite dėmesį, kad automatiniai vertimai gali turėti klaidų ar netikslumų. Originalus dokumentas jo gimtąja kalba turėtų būti laikomas autoritetingu šaltiniu. Kritinei informacijai rekomenduojama profesionali žmogaus vertimo paslauga. Mes neprisiimame atsakomybės už nesusipratimus ar klaidingus interpretavimus, atsiradusius naudojant šį vertimą.