Přeskočit na obsah
_CORE
AI & Agentic Systems Core Informační Systémy Cloud & Platform Engineering Data Platforma & Integrace Security & Compliance QA, Testing & Observability IoT, Automatizace & Robotika Mobile & Digital Banky & Finance Pojišťovnictví Veřejná správa Obrana & Bezpečnost Zdravotnictví Energetika & Utility Telco & Média Průmysl & Výroba Logistika & E-commerce Retail & Loyalty
Reference Technologie Blog Knowledge Base O nás Spolupráce Kariéra
Pojďme to probrat

Backbone.js — konecne strukturovany JavaScript

08. 11. 2011 5 min čtení CORE SYSTEMSdevelopment

Nase JavaScript soubory rostou. Co zacalo jako par radku jQuery pro validaci formulare a AJAX volani, se zmenilo v tisice radku neprehledneho kodu. jQuery je skvely pro manipulaci s DOM, ale neposkytuje zadnou strukturu pro organizaci aplikacni logiky. Backbone.js od Jeremyho Ashkenase resi presne tento problem — prinasi modely, kolekce, pohledy a router do frontendoveho vyvoje.

Proc potrebujeme strukturu na frontendu

Pred tremi lety byl typicky webovy frontend jednoduchy — server vyrendrovál HTML, jQuery pridalo par interaktivnich efektu. Ale s rostoucimi ocekavanimi uzivatelu se frontend stal slozitejsim. Gmail, Google Maps, Facebook — tyto aplikace bezi prevazne v prohlizeci a server slouzi hlavne jako API. Kdyz mate tisice radku JavaScriptu bez jasne struktury, kazda zmena se stava rizikem.

Problem neni v jQuery — jQuery dela presne to, k cemu byl navrzen. Problem je v absenci architektonickych vzoru na frontendu. Na serveru mame MVC (Spring MVC, Rails, Django), dependency injection, service layer. Na frontendu jsme meli soubor plny $() selektoru a anonymnich funkci. Backbone.js je prvni siroce adoptovany pokus o zmenú tohoto stavu.

Modely (Models)

Backbone Model reprezentuje datovou entitu — uzivatele, produkt, objednavku. Model obsahuje atributy (data), validacni logiku a metody pro komunikaci se serverem (save, fetch, destroy). Klicova vlastnost je, ze model vyvolava udalosti pri zmene atributu — kdyz se zmeni jmeno uzivatele, vsechny pohledy, ktere toto jmeno zobrazuji, se automaticky aktualizuji.

Toto je zakladni princip data binding — Model je jediny zdroj pravdy a pohledy na nej reagují. V jQuery svete jsme typicky meli data ulozena v DOM (v atributech, v textu elementu) a JavaScript je odsud cet a tam zapisoval. S Backbone modely jsou data oddelena od prezentace. Chcete zmenit jmeno uzivatele? Zmenite atribut modelu a vsechny pohledy se aktualizuji samy.

Model take abstrahuji komunikaci se serverem. Backbone predpoklada RESTful JSON API. Volani model.save() posle POST nebo PUT pozadavek na server, model.fetch() nacte data pres GET, model.destroy() posle DELETE. URL se automaticky odvozuje z korenovahe URL kolekce a ID modelu. Tato konvence nad konfiguraci vyrazne snizuje boilerplate kod.

Kolekce (Collections)

Collection je usporadana množina modelu stejneho typu. Kolekce uzivatelu, kolekce produktu, kolekce objednavek. Collection poskytuje metody pro pridavani, odebirani, filtrování a razení modelu. Díky integraci s Underscore.js (sourozenec Backbone) mate k dispozici bohatou sadu funkcionalnich metod — map, filter, reduce, find, sortBy, groupBy.

Stejne jako modely, kolekce vyvolvavaji udalosti — add, remove, reset, sort. Pohled zobrazujici seznam produktu muze naslouchat na tyto udalosti a automaticky se prekreslovat pri zmene dat. Pridani noveho produktu? Kolekce vyvola udalost add, pohled prida novy radek do seznamu. Smazani produktu? Udalost remove, pohled odebere radek. Zadna manualni manipulace s DOM.

Pohledy (Views)

Backbone View je zodpovedny za renderovani HTML a zpracovani uzivatelsych interakci. Kazdy pohled je spojen s DOM elementem a muze naslouchat na DOM udalosti (click, submit, keyup) v ramci sveho elementu. Pohled typicky nasloucha na zmeny v modelu a pri zmene se prerenderuje.

Backbone nepredpisuje sablonovy system — muzete pouzit cokoliv od jednoduchych string templates pres Underscore templates az po Handlebars nebo Mustache. My pouzivame Handlebars, protoze nabizi logicke helpery a partials bez toho, aby umoznoval slozitou logiku v sablonach (separation of concerns). Pohled pripravi data z modelu, preda je sablone a vysledne HTML vlozi do DOM.

Dulezity detail — Backbone views nezajistuji automaticky efektivni prekreslovani. Kdyz zavolate render(), cely obsah pohledu se nahradi novym HTML. Pro jednoduche pohledy to neni problem, ale pro slozite seznamy s desitkami polozek to muze byt pomale. Optimalizace vyzaduje granularnejsi aktualizace — misto prerenderovani celeho seznamu aktualizovat jen zmeneny radek. To je oblast, kde Backbone nechava rozhodnuti na vyvojari.

Router

Backbone Router mapuje URL hash fragmenty na funkce. Kdyz uzivatel prejde na #users/123, router zavola funkci, ktera nacte uzivatele s ID 123 a zobrazi prislusny pohled. To umoznuje vytvorit single-page aplikaci s plnou podporou historie prohlizece a bookmarků. Uzivatel muze pouzivat tlacitka zpet a vpred, sdílet URL a obnovit stranku bez ztraty stavu.

Router je jednodussi nez routery v serverovych frameworcich — nema middleware, nema named routes, nema nestovani. Pro slozitejsi aplikace to muze byt omezeni a casto vidime developery, kteří si vytvareji vlastní abstrakci nad Backbone routerem. Ale pro zakladni use case je vestaveny router dostacujici.

Nase architektura s Backbone

Po nekolika projektech jsme si vyvinuli standardni architekturu pro Backbone aplikace. Na vrcholu je Application objekt, ktery inicializuje router a sdilene sluzby. Router deleguje na Controller objekty (Backbone je nema nativne, pridali jsme si je), ktere koordinuji nacitání dat a vytvareni pohledu. Pohledy jsou hierarchicke — hlavni layout pohled obsahuje regionya kazdy region hostí specificky pod-pohled.

Pro komunikaci mezi nesouvisejicimi pohledy pouzivame event aggregator — globalni event bus, na ktery mohou pohledy vyvolavat a naslouchat udalosti. To zamezuje primym zavislostem mezi pohledy a dela kod flexibilnejsim. Napriklad pohled košíku nevola přímo pohled produktového katalogu — místo toho vyvolá událost product:add-to-cart a košík naslouchá.

Tato architektura je inspirovana frameworkem Marionette.js od Derricka Baileye, ktery pridava do Backbone koncepty jako regions, layouts a composite views. Zvazujeme jeho plnou adopci pro dalsi projekt.

Testovani

Backbone kod je dobre testovatelny, protoze modely a kolekce nejsou zavisle na DOM. Muzete testovat validaci modelu, vypocitane atributy a interakci s API pomoci unit testu bez prohlizece. Pro testovani pouzivame Jasmine — BDD framework pro JavaScript s cistou syntaxi (describe, it, expect). Pro pohledy testujeme, ze spravne renderuji HTML a reaguji na udalosti.

Mockování API volání zajistujeme pres Sinon.js FakeServer, ktery zachytava AJAX pozadavky a vracía predpripravene odpovedi. To umoznuje testovat cely flow — od nacteni dat pres model az po zobrazeni v pohledu — bez skutecneho serveru.

Limity Backbone

Backbone je zámerne minimalisticky. Jeremy Ashkenas ho navrhl jako „minimalni sadu nastroju pro strukturovani JavaScriptu”, ne jako kompletni framework. To znamená, ze spoustu veci musite resit sami — memory management (odhlasovani event listeneru pri ruseni pohledu), efektivni renderovani seznamu, komunikace mezi pohledy, lazy loading modulu. Pro kazdy z techto problemu existuji reseni v komunite, ale nejsou soucasti core frameworku.

Take je dulezite si uvedomit, ze Backbone neni jedina moznost. Knockout.js nabizi deklarativni data binding. Ember.js je kompletnejsi framework s konvencemi. A na horizontu se rysuje AngularJS od Googlu, ktery slibuje radikalne jiny pristup. Ale dnes, na podzim 2011, je Backbone nejzralejsi a nejsirseji adoptovana volba pro strukturovani frontendoveho JavaScriptu.

Zaver

Backbone.js prinasi tolik potrebnou strukturu do frontendoveho vyvoje. Models, Collections, Views a Router jsou zakladni stavebni kameny, ktere umoznuji organizovat rostouci JavaScript kodovou bazi. Neni to stribrna kulka — vyzaduje disciplinu a doplnkove knihovny — ale je to obrovský krok vpred oproti jQuery spaghetti. Doporucujeme kazdemu tymu, ktery stavi netrivialni webovou aplikaci.

backbone.jsjavascriptmvc