Prosty edytorek markdown (eksperyment z backbone.js)

03 May 2012

W ramach zabawy z backbone.js złożyłem banalnie prosty edytorek markdown na HTML działający w trybie live. Jest to jeden z prostrzych przykładów użycia backbone.js - może się więc komuś przydać do nauki tego frameworka. Samym konwertowaniem na HTML zajmuje sie showdown. W aplikacji można wyróżnić trzy backbonowe widoki oraz jeden model. Kod źródłowy znajduje się tutaj i mówi on sam za siebie - postaram się jednak opisać go tutaj własnymi słowami. Najlepiej jest czytać poniższy tekst mając jednoczesnie kod źródłowy przed oczami - będe tutaj opisywał wszystko mniej więcej po kolei.

Model

Model (obiekt Data) zawiera trzy własciwości - aktualną zawartość czyli tekst markdown (markdownText), czas przetwarzania na HTML (parsingTime) oraz czas renderowania HTML (renderingTime). Model opisuje on aktualny stan aplikacji. W momencie zmiany dowonlej właściwości, model wysyła zdarzenie (np. change:markdownText), na które reagować mogą inne części aplikacji (np. widoki). Model jest modyfikowany w wyniku działań użytkownika (w momencie wpisywania znaków w textarea). Za modyfikację widoku w tym przykładzie odpowiedzialny jest widok zawierający textarea (obiekt MarkdownPanel).

Widoki

Obiektom reprezentującym widoki odpowiadają poszczególne elementy div. Każdy obiekt div zajmuje się modyfikowaniem tylko tego co znajduje się w obrębie jego elementu. W tym przykładzie mamy trzy widoki, odpowiadające trzem prostokątnym sekcjom widocznym w przykładzie.

  • MarkdownPanel - zawiera textarea, w wyniku zdarzenia keyup generowanego z textarea, wykonywana jest metoda updateModel tego widoku. W tej metodzie ustawiamy wartość markdownText na taką jaką aktualnie ma pole tekstowe.
  • PreviewPanel - zawiera on div znajdujący sie po prawej stronie, widok ten nasłuchuje zdarzenia generowanego w wyniku modyfikacji własciwości markdownText modelu. W wyniku tego zdarzenia wykonywana jest metoda render tego obiektu. W niej aktualna wartość markdownText jest przetwarzana na HTML za pomocą konwertera showdown. Jednocześnie obliczany jest czas przetwarzania i wynik pomiaru zapisywany jest w modelu. Kod HTML wygenerowany przez showdown wyswietlany jest w obrębie głównego diva tego widoku.
  • StatsPanel - reprezentuje div znajdujący się na dole strony. Wyswietlany jest w nim czas ostatniego przetwarzania markdown na HTML. Działa to na tej samej zasadzie do PreviewPanel lecz na innych polach modelu i bez koniecznosci używania zewnętrznego obiektu tzn. konwertera showndown. W wyniku tego, że PreviewPanel modyfikuje właściwość parsingTime modelu generowane jest zdarzenie. Na zdarzenie reagujemy wykonując metode render, która aktualizuje tekst wyświetlany w divie znajdującym się na dole.

Inicjalizacja

Powyżej opisane obiekty są czyms w stylu klas ("czymś w stylu" ponieważ w JS nie ma klas ale są prototypy) na podstawie, których tworzymy docelowe obiekty. Warto w tym miejscu podkreslić, że aby jak najbardziej uniezależnić od siebie widoki wszystkie niezbędne im do działania rzeczy przekazujemy do konstruktora jako parametry - a nie hardcodujemy wewnątrz metod. Trzeba sie wystrzegać przez każdorazowym tworzeniem nowych - lokalnych obiektów gdy nie ma takiej potrzeby. Często spotykanym błędem jest każdorazowe używanie jQuery by na nowo odnaleźć dany element na stronie - podczas gdy wystarczy odnaleźć go raz i zapamiętać wynik w polu.

Zakończenie

Jest to jeden z prostszych przykładów użycia backbone.js. Ilustruje on podstawową jego ideę - aplikacja powinna składać się z szeregu modułów, które porozumiewają się między sobą nie bezpośrednio lecz w reakcji na zdarzenia, generowane manualnie lub automatycznie przez model.