Na minulom cvičení ste sa naučili ako prečítať údaje z formulára a tiež ako ich uložiť do
window.localStorage
a odtiaľ prečítať.
Dnes si vyskúšate, ako tieto údaje namiesto vypisovania do konzoly vložiť priamo do HTML kódu stránky.
Urobíte to dvoma spôsobmi:
Vyskúšate si to najprv na príklade blogu o obľúbených stromoch (My Favourite Trees) a potom vo vašom vlastnom blogovacom systéme.
Na rozdiel od predchádzajúceho cvičenia, bude váš JavaScript kód umiestnený
vo viacerých samostatných skriptoch typu modul [5] a jednotlivé moduly budú vytvorené ako triedy [6].
Poznámka: Všetko potrebné na splnenie dnešných úloh ste sa dozvedeli z prednášok 5 až 7 ([1], [2], [3]).
Na podrobné oboznámenie sa s jazykom JavaScript odporúčame zdroje [7] a [8].
Ako používať knižnicu Mustache zistíte z prednášky [4], príkladov [15] a dokumentácie na [13].
S problematikou, ktorú máte dnes zvládnuť vás podrobne oboznámia aj prvé dve úlohy tohto cvičenia.
name
, created
a comment
.
Vy teraz doplníte spracovanie údajov do html v upravenej verzii príkladu 57myTreesFormLStorageHtml, kde je aj položka willReturn
ale chýba kód na spracovanie do HTML.
Úloha 1: V aplikácii myTreesFormLStorageHtmlWr doplňte spracovanie údajov do HTML tak, aby sa:
opinions
,
zobrazili v elemente div
s id="opinionsContainer"
.
newOpinion
) nezapísal iba do poľa opinions
ale
pridal aj do HTML na koniec elementu div
s id="opinionsContainer"
.
created
zobrazte iba dátum, nie čas.
Na vytvorenie HTML kódu využite
šablónové literály.
Váš JavaScript kód píšte vo forme modulov [5], kde jednotlivé moduly sú triedami [6].
//TODO
v JavaScript súboroch aplikácie vám napovedia kde je aký kód potrebné vložiť. Alebo môžete použiť nasledujúci kompletný postup riešenia:
opinionsHandler.js
s triedou OpinionsHandler
, ktorý je v podpriečinku js
.
//TODO Add opinionsElm property, referencing the div with id given by the parameter opinionsListElmId
//TODO Add opinionsFrmElm property, referencing the form with id given by the parameter opinionsFormElmId
nahraďte kódom
this.opinionsElm = document.getElementById(opinionsListElmId);
this.opinionsFrmElm = document.getElementById("opnFrm");
Urobili sme to, aby sme príslušné elementy nemuseli opätovne
vyhľadávať v DOM. Ušetríme tak čas aj energiu zariadenia na ktorom bude aplikácia zobrazená.
opinion2html
nahraďte komentár
//TODO finish opinion2html
kódom
const opinionTemplate=
`
<section>
<h3>${opinion.name} <i>(${(new Date(opinion.created)).toDateString()})</i></h3>
<p>${opinion.comment}</p>
<p>${opinion.willReturn?"I will return to this page.":"Sorry, one visit was enough."}</p>
</section>`;
return opinionTemplate;
Tu je využitý šablónový literál opinionTemplate
na vyrobenie HTML kódu z údajov v objekte
opinion
.
Všimnite si, že v šablónových literáloch môžeme používať aj zložitejšie výrazy ako len názvy premenných
alebo ich vlastností (položiek). Na spracovanie vlastnosti willReturn
sme využili
ternárny operátor.
opinionArray2html
nahraďte komentár
//TODO finish opinionArray2html
kódom
return sourceData.reduce((htmlWithOpinions,opn) => htmlWithOpinions+ this.opinion2html(opn),"");
Tento kód vygeneruje HTML so všetkými názormi z poľa sourceData
(Pri jej volaní ako parameter použijeme pole opinions
).
Poznámka:
Funkcia opinionArray2html
využíva funkciu Array.prototype.reduce
.
Ak sa vám táto zdá príliš zložitá na pochopenie,
tu je jednoduchšia verzia kódu opinionArray2html
, ktorá používa príkaz cyklu
for...of
:
let htmlWithOpinions="";
for(const opn of sourceData){
htmlWithOpinions += this.opinion2html(opn);
}
return htmlWithOpinions;
init
komentár
//TODO render opinions to html
nahraďte kódom
this.opinionsElm.innerHTML = this.opinionArray2html(this.opinions);
Takto sa obsah poľa opinions
, ktorý funkcia opinionArray2html
spracovala do HTML,
dostane do elementu opinionsElm
(div
).
Tento kód sa vykoná pri načítaní stránky (aplikácie) v prehliadači.
//TODO add the new opinion to HTML
vo funkcii processOpnFrmData
nahraďte kódom
this.opinionsElm.innerHTML+=this.opinion2html(newOpinion);
Tým sa práve spracovaný názor (z opinion
) dostane do HTML na koniec elementu opinionsElm
.
myTreesFormLStorageHtmlWr.js
komentár
//TODO create the object window.opnsHndlr of the class OpinionsHandler and run its init method
nahraďte kódom
window.opnsHndlr = new OpinionsHandler("opnFrm","opinionsContainer");
window.opnsHndlr.init();
Takto vytvoríte a inicializujete objekt opnsHndlr
triedy OpinionsHandler
, prepojený na príslušné html elementy.
js
vytvorte JavaScript modul opinionsHandlerMustache.js
s triedou OpinionsHandlerMustache
, ktorá je potomkom triedy OpinionsHandler
a líši sa od nej v tom, že namiesto šablónového literálu používa šablónu systému Mustache. Mustache šablónu vložte ako nový element do myTreesFormLStorageHtmlWr.html
.
Skript myTreesFormLStorageHtmlWr.js
upravte tak, aby použil objekt triedy OpinionsHandlerMustache
namiesto OpinionsHandler
.
57myTreesFormLStorageHtmlWr.html
doplňte nový element
<script id="mTmplOneOpinion" type="text/template">
<section>
<h3>{{name}} <i>{{createdDate}}</i></h3>
<p>{{comment}}</p>
<p>{{willReturnMessage}}</p>
</section>
</script>
Nie je dôležité, kde presne ho vložíte. Môžete ho dať napríklad pred element script
, ktorý ste vložili v predchádzajúcom kroku.
Tento nový element obsahuje Mustache šablónu pre zobrazenie názoru.
V šablóne sú dve vlastnosti (položky), ktoré sa v objektoch nenachádzajú.
Sú to createdDate
a willReturnMessage
.
Je to preto, lebo hodnoty z položiek created
a willReturn
,
ktoré v objekte sú, nechceme zobraziť priamo ale až po spracovaní.
Keďže Mustache šablóny sú bez logiky (logic-less), takéto spracovanie priamo v šablóne neumožňujú.
Musíme ho teda urobiť predtým a spracované údaje do objektu pridať.
Možno sa vám to zdá obmedzujúce, no autori Mustache takto chceli zabrániť tomu,
aby sa do ich šablón dostali príkazy programovacieho jazyka.
js
vytvorte JavaScript modul opinionsHandlerMustache.js
a vložte doň kód
import OpinionsHandler from "./opinionsHandler.js";
import Mustache from "./mustache.js";
export default class OpinionsHandlerMustache extends OpinionsHandler{
constructor(opinionsFormElmId, opinionsListElmId,templateElmId) {
//call the constructor from the superclass:
super(opinionsFormElmId, opinionsListElmId);
//get the template:
this.mustacheTemplate=document.getElementById(templateElmId).innerHTML;
}
opinion2html(opinion){
//in the case of Mustache, we must prepare data beforehand:
opinion.createdDate=(new Date(opinion.created)).toDateString();
//use the Mustache:
const htmlWOp = Mustache.render(this.mustacheTemplate,opinion);
//delete the createdDate item as we created it only for the template rendering:
delete(opinion.createdDate);
//return the rendered HTML:
return htmlWOp;
}
}
Táto trieda funguje rovnako ako OpinionsHandler
, no namiesto šablónového literálu používa Mustache šablónu.
Všimnite si, že do objektu opinion
sme pred použitím šablóny pridali vlastnosti createdDate
a willReturnMessage
.
Po jej použití sme ich odstránili.
Súbor mustache.js
, ktorý sa v priečinku js
už nachádza, je mustache.mjs
stiahnutý zo stránky [14] a premenovaný na mustache.js
.
Poznámka:
V mnohých prípadoch je považované za bezpečnejšie
namiesto modifikácie pôvodných údajov vytvoriť nové údaje,
určené iba pre zobrazenie. Tento spôsob ochráni
pôvodné údaje pred nechcenou modifikáciou.
Na druhej strane je však zdĺhavejší a vyžaduje viac pamäte.
Ak chcete aplikovať tento spôsob, použite pre funkciu opinion2html
nasledujúci kód:
const opinionView ={
name: opinion.name,
comment: opinion.comment,
createdDate: (new Date(opinion.created)).toDateString(),
willReturnMessage:
opinion.willReturn?"I will return to this page.":"Sorry, one visit was enough."
};
return Mustache.render(this.mustacheTemplate,opinionView);
myTreesFormLStorageHtmlWr.js
riadky
import OpinionsHandler from "./opinionsHandler.js";
window.drMenuCntrl = new DropdownMenuControl("menuIts", "menuTitle", "mnShow");
window.opnsHndlr = new OpinionsHandler("opnFrm","opinionsContainer");
window.opnsHndlr.init();
nahraďte kódom
import OpinionsHandlerMustache from "./opinionsHandlerMustache.js";
window.drMenuCntrl = new DropdownMenuControl("menuIts", "menuTitle", "mnShow");
window.opnsHndlr = new OpinionsHandlerMustache("opnFrm","opinionsContainer","mTmplOneOpinion");
window.opnsHndlr.init();
OpinionsHandler
a OpinionsHandlerMustache
,
uložené v samostatných moduloch v adresári js
, tak ako v predchádzajúcich úlohách.
Poznámka: Keď použijete Mustache, môžete získať viac bodov ako za použitie šablónových literálov. (podrobnosti zistíte v popise k nasledujúcemu cvičeniu).