Require.js – AMD w praktyce

Już kilkukrotnie poruszałem temat tworzenia modułów (czasem nawet „klas”) w JavaScripcie. Tym razem coś nowego – asynchroniczne definiowanie modułów. W skrócie AMD (ang. asynchronous module definition). Coraz więcej znanych frameworków i bibliotek wykorzystuje właśnie to podejście (choćby Dojo i jQuery).

W tym wpisie spróbuję pokazać dlaczego powstało takie rozwiązanie oraz przedstawić kilka prostych zastosowań.

Na początek warto:

Rozwijanie listy po kliknięciu na dijit.form.FilteringSelect / ComboBox

W Dojo Toolkit jest cały zestaw widgetów pozwalających budować bardzo nowoczesne aplikacje webowe. W ty wpisie zajmę się dwoma (spokrewnionymi) kontrolkami:

  • dijit.form.FilteringSelect
  • dijit.form.ComboBox

autouzupełnianie dijit.form.FilteringSelect

Co one robią?

Co z nimi nie tak, skoro mam zamiar im poświęcić cały wpis? Kolejno – są to komponenty zastępujące zwykły HTML-owy znacznik <select />. Są bardzo przyjazne dla oka, pozwalają nie tylko na wybór pozycji z listy dostępnych, ale także na wpisywanie własnych (mechanizm podpowiedzi), dodatkowo bardzo dobrze współdziałają z data store. Słowem – używać, nie umierać ;).

Jednak posiadają jedną dużą wadę funkcjonalną – aby rozwinąć listę trzeba kliknąć dokładnie,tylko i wyłącznie w strzałeczkę sugerującą rozwijanie.

demo online

Czytaj dalej Rozwijanie listy po kliknięciu na dijit.form.FilteringSelect / ComboBox

REST – ciekawszy sposób na komunikację client-server

REST (ang. Representational State Transfer) jest wzorcem narzucającym dobre praktyki tworzenia architektury aplikacji rozproszonych. RESTful Webservices (inaczej RESTful web API) jest usługą sieciową zaimplementowaną na bazie protokołu HTTP i głównych zasad wzorca REST. W tym wpisie postaram się pokazać (bardzo) podstawowe założenia.

Ważnym założeniem REST jest istnienie zasobów (ang. resources) jako źródeł danych a także żądana akcja. Ale może po kolei…

Zapomniane metody HTTP w Ajaksie

Komunikując się z serwerem najczęściej korzysta się z dwóch metod:

  • GET
  • POST

Co więcej, często wykorzystuje się je nieprzemyślany sposób (aby nie powiedzieć losowy). Nigdy nie wiadomo, czy żądanie doda, usunie, nadpisze czy tylko pobierze dane z serwera. A szkoda, bo przecież o ile ładniej jest patrzeć w konsole Firebuga i po samym rodzaju metody odczytywać jakiego rodzaju operacja została wywołana.

Tytułowe „zapomniane” metody to (jest ich więcej, ale nie są potrzebne dla tego wpisu):

dijit.Dialog.onMove()

Dojo posiada pokaźny zbiór widgetów (dijit – Dojo widget). W tym wpisie zajmiemy się kontrolką `dijit.Dialog’ oraz (nieistniejącym domyślnie) zdarzeniem `onMove’. Owe zdarzenie zostanie utworzone z wykorzystaniem istniejących mechanizmów dojo.

Proste okienko

Na początek pokażę kod prostego okienka `dijit.Dialog’:

[javascript]dojo.require("dijit.Dialog");
dojo.ready(function(){
var dialog = new dijit.Dialog({
title: "Okienko",
style: "width: 200px; height: 200px;",
content : "Witaj świecie"
});
dialog.startup();
dialog.show();
});[/javascript]

dojo.require("dijit.Dialog");
dojo.ready(function(){
	var dialog = new dijit.Dialog({
		title: "Okienko",
		style: "width: 200px; height: 200px;",
		content : "Witaj świecie"
	});
	dialog.startup();
	dialog.show();
});

demo online

Do konstruktora przekazałem tylko kilka parametrów. Aby zapoznać się z pozostałymi zapraszam do dokumentacji*. W kodzie zamieszczonym powyżej oczywiście nie ma jeszcze obsługi zdarzenia `onMove’. Aby je dodać wykorzystam mechanizm `dojo.subscribe‚.

Wykorzystanie `dojo.subscribe’ do przechwycenia przesunięcia

Skoro mamy okno, przechwyćmy moment, w którym zostanie przesunięte. Kontrolka okienka publikuje informacje o swoim przemieszczeniu w kanale ‚/dnd/move/stop‚. Wystarczy zatem zasubskrybować ten kanał:

[javascript]dojo.require("dijit.Dialog");
dojo.ready(function()
{
var dialog = new dijit.Dialog({
title: "Okienko",
style: "width: 200px; height: 200px;",
content : "Witaj świecie"
});
dojo.subscribe(‚/dnd/move/stop’, function(mover)
{
alert(‚Poruszyłeś mnie!’);
});
dialog.startup();
dialog.show();
});[/javascript]

demo online

OK, już mamy prymitywną obsługę „zdarzenia” `onMove’. Jakie są główne problemy:

  • na ten sam kanał publikują wszystkie wigety, a więc nie mamy obsługi konkretnie `onMove’ tego okienka,
  • nie jest to zbyt piękne rozwiązanie, raczej proteza.

Dodanie metody `onMove’

Aby ulepszyć poprzednie rozwiązanie musimy po pierwsze rozpoznawać konkretne okno. Po drugie musimy po rozpoznaniu wywołać metodę `onMove’. Kod jest dużo prostszy niż by się to wydawało:

[javascript]dojo.require("dijit.Dialog");
dojo.ready(function()
{
function createDijitDialogWithOnMoveEvent(title, content)
{
var dialog = new dijit.Dialog({
title: title,
style: "width: 200px; height: 200px;",
content : content,
onMove : function() {}
});
dojo.subscribe(‚/dnd/move/stop’, function(mover)
{
// rozpoznanie okna
if (mover.node.id === dialog.id)
{
dialog.onMove();
}
});
dialog.startup();
dialog.show();

return dialog;
}
var x = createDijitDialogWithOnMoveEvent("dijit.Dialog.onMove", "Witaj świecie!");
dojo.connect(x, ‚onMove’, function()
{
alert(‚poruszyłeś mnie!’);
});
});[/javascript]

demo online

Każdy widget dojo posiada swój unikalny id. Pozwala to podczas odczytywania z kanału sprawdzić, czy mamy do czynienia z tym oknem, o które aktualnie nam chodzi.

Następnie przypisanie odpowiedniej funkcji obsługi zdarzenia jest już formalnością. Opis mechanizmy dojo.connect/disconnect można znaleźć w jednym z wcześniejszych wpisów:

*A niech będzie – tu się wyżyję. Dojo Toolkit do wersji 1.6 posiadał bardzo przyjemną i ułatwiającą życie dokumentację (linkowany przykład `dijit.Menu’) w postaci opis-przykład-kod do skopiowania. W 1.7 stwierdzono chyba, że życie programisty nie może być takie piękne i zdecydowanie zepsuto IMVHO bardzo przydatne zasoby – dla kontrastu ten sam dijit, dokumentacja w wersji 1.7 – spróbuj uruchomić przykład lokalnie.

EDIT (2013-02-06): W wersji 1.8 naprawiono wyżej opisane błędy.

Wywoływanie zdarzeń z poziomu JavaScript

Obsługa zdarzeń to jeden z częściej wykorzystywanych mechanizmów na nowoczesnych stronach WWW. Czasem jednak chcielibyśmy nie tyle przypisać pewne zdarzenie, co z poziomu JavaScript je wywołać. W tym wpisie pokażę jak to zrobić wykorzystując stare i nowe sposoby, zarówno w przeglądarkach, jak i w IE (nie wszystkie przykłady będą działać w IE. Opis, co zrobić, aby załatać tę niespójność znajdziesz na końcu wpisu).

Czytaj dalej Wywoływanie zdarzeń z poziomu JavaScript

Parsowanie JSON

JSON (ang. JavaScript Object Notation) jest bardzo przyjemnym formatem wymiany danych. W tym wpisie postaram się pokazać kilka sposobów na parsowanie ciągu znaków zgodnego (lub zbliżonego) z JSON. Z zasadami tworzenia poprawnego JSON można zapoznać się na oficjalnej stronie.

Opisane sposoby:

  • funkcja `eval’ (natywna funkcja JS – archaiczne rozwiązanie)
  • biblioteka json2 (obiekt `JSON’) by Doug Crockford
  • biblioteka json_parse’ (funkcja `json_parse’)  by Doug Crockford
  • biblioteka json_sans_eval (funkcja jsonParse) by Mike Samuel
  • obiekt JSON = { stringify : function, parse : function } (natywny obiekt JS – nowsze przeglądarki)
  • parser JSON w jQuery
  • parser JSON w Dojo Toolkit

Czytaj dalej Parsowanie JSON

Książka: „HTML5 i CSS3. Standardy przyszłości”

HTML5 i CSS3. Standardy przyszłościHTML5 i CSS3. Standardy przyszłości

Nadchodzi (kolejna!?) rewolucja w tworzeniu stron internetowych. A może już aplikacji webowych? Tym razem u jej podstaw stać będzie HTML5.

Czym jest HTML5?

To już nie tylko określenie nowej wersji starego, dobrze znanego HTML. To już jest słowo klucz jak Ajax, czy Web 2.0. Wszystko, co nowoczesne powoli zaczyna być po prostu określane mianem HTML5 – w tym nowe rozwiązania JavaScript (jak choćby Canvas, geolokalizacja, localstorage itp.) czy CSS3. Czytaj dalej Książka: „HTML5 i CSS3. Standardy przyszłości”