Witam.
Tym razem chciałbym pokazać, pochwalić się własnym tworem, do obsługi frontendu z poziomu PHP ;)
Demo:
http://www.tattool.co/xplore/
Więcej źródeł przykładów:
https://github.com/bordeux/xvEngine/
<font size="5"> Z czym się to je </span>
Framework bazuje na 3 istotach
- komponenty
- serwisy
- handlery
<font size="5"> Komponenty </span>
Komponent to jest widok, każdy komponent posiada 3 pliki, np.
- ButtonComponent.js - klasa w JavaScripcie, która zawiera metody i opcje przycisku
- ButtonComponent.scss - ostylowanie
- ButtonComponent.php - interfejs dla PHP, który pośrednio odwozruje metody z klasy JavaScriptiowej
Komponent jest tutaj właśnie czymś w postaći przycisku, specyfinczego inputu (np colorInput, imageInput itp), czy też okna modalnego.
<font size="5"> Serwisy </span>
Są to klasy, które działają nie zależnie od widoku, działają w tle, w każdym momencie można do nich się odwołać. Np. serwis do ustawiania metatagów
application.services.utils.metaTags.add("meta-key", "meta-value");
czy też do pokazania progressu wczytywania strony
application.services.ui.progress.show();
<font size="5"> Handlery </span>
Elementy, które scalają logiczną część aplikacji. Podstawowe to:
- ActionHandler(string $idKomponentu) - pobiera referencje do jakiegoś komponentu, który już istnieje, aby wykonywać na nim metody.
- RequestHandler(string $url) - wykonuje request do danej strony. Wynikiem tego requestu jest kolejna paczka Handlerów.
- ServiceHandler(string $nameSpaceSerwisu) - pobiera referencje do serwisu, aby wykonywac na nim metody
- PageHandler(AbstractComponent $component) - ustawia główny komponent do strony, czyli ustawia go w body, usuwajac poprzedni.
- HistoryHandler(string $url) - ustawia adres URL w przeglądarce poprzez history API w HTML5
<font size="5"> Przykład w praktyce </span>
Mamy na celu stworzyć przycisk. Po naciśnięciu na niego, ma się zmienić tekst przycisku na "Loading...", następnie zrobić request do serwera, w celu pobrania informacji.
Tak więc najpierw musimy stworzyć stronę z przyciskiem:
<?php
//...
/**
* @Route("/przycisk/")
*/
public function indexAction(){
$this->response->addHandler(function(){
$page = new PageHandler($this->getView());
$page->setPageName("przycisk")
return $page;
}, $this);
return $this->response;
}
public function getView(){
$view = new ButtonComponent("button1");
$view->setText("Nacisnij mnie!");
$view->on("onClick", function() use($view){//event gdy uzytkownik nacisnie guzik
$action = new ActionHandler($view->getId()); //pobieramy referencje do klasy przycisku
$action->setText("Loading..."); //zmieniamy label przycisku
$action->off("onClick"); //odbindujemy akcje na przycisku, by uzytkownik nie kliknal 2x
return $action;
});
$view->on("onClick", function() use($view){
$request = new RequestHandler("/przycisk/dalej/"); //wykonujemy request do podanej strony
$request->setOption("progress", true); //zarazem ma sie pokazac progress
$requet->addPost("aktualnyLabel", CustomParam::Get($view->getId())->getText()); //w poscie doslemy sobie aktualny label przycisku
return $request;
});
return $view;
}
//...
?>
W ten sposób utworzyliśmy przycisk. Teraz zróbmy odpowiedź serwera :)
<?php
//...
/**
* @Route("/przycisk/dalej/")
*/
public function indexAction(){
$this->response->addHandler(function(){
$action = new ActionHandler("button1");
$action->setText("Dziękuje!"); //zmieniam po requescie label przycisku
return $action;
}, $this);
return $this->response;
}
//...
?>
<font size="5"> Zalety </span>
- Jakość kodu JS jest bardzo wysoka. Każdy komponent ma swoj namespace wykonany na podstawie struktury katalogu. Wszystko napisane obiektowo, że nie ma nigdzie funkcji globalnych itp
- Każdy element ma swoje miejsce, i jest odizolowane od reszty. Handlery łączą elementy, w postaci serwis z komponentem, komponent z serwisem itp
- Można stworzyć cały portal bez przeładowywania strony. Wszystko na ajaxie, z obsługą histori przeglądarki itp.
- Nie spotkałem się jeszcze z efektem wąskiego gardła. Czasami jest ciężka logika jakiegoś zdarzenia, dlatego też takie cięzkie elementy można napisać w czystym JSie (dirty workaround'y) w postaci serwisu, i odwolywac sie do tego sewisu z poziomu komponentu.
- Lubie placki
- Po napisaniu wszystkich komponentów, które na stronie wysępują, mało kiedy wchodzę w część JS'ową. Zajmuje się tym co kocham - programowaniem, niż wkurzaniem się JavaScriptem :)
<font size="5"> Wtf, nie lepiej pisać w czystym htmlu? </span>
Pisząc standardowo, w htmlu i jquery można dojść, że portal staje sie bardziej skomplikowany. Powstają niezliczone ilości JavaScriptu , przez co ciężko się połapać. Szczególnie gdy jest rotacja pracowników, gdzie nowy pracownik nie zna wszystkich eventow na stronie.
Rozwiązanie co przedstawiam narzuca pewne rygory i pojmanie logiki frameworka. Trzeba tylko wiedzieć że wszystko jest obiektem, i wywołujesz na tych obiektach metody. Wraz z wzrostem portalu, nie zmienia się trudność kodu :)
<font size="5"> AngularJS jest, ReactJS, po co to pisałeś? </span>
A bo kiedy zaczynałem, Angular to była nowość, a ReactJS nawet w głowach nie było :)
Czekam na opinie, komentarze, jaki kolwiek feedback :)