Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Archiwum Pro _ Ładowanie akcji oraz widoków w FW

Napisany przez: menic 11.01.2007, 16:09:16

Będe tu zamieszczał pytania odnoscie działania FW, oraz róznych kruczków smile.gif
Pierwsze z nich to pobieranie aktualnej akcji i modułu. Moge to zrobić pobierając z adresu w Kontrolerze module oraz action. Jesli wartosci sa puste podstawiamy domyslne. Bułka z masłem. Jednak co jesli rozszerzymy funkcjonalnosc o znaną funkcje forward()? Przekierowywuje ona do innego modułu i/lub akcji bez zmiany parametrów w adresie. I co teraz? W adresie mamy dane dotyczącego poprzedniej akcji, wiec pobieranie z adresu nie ma sensu. W tym wypadku odpada pobieranie z adresu. Jak to najlepiej rozwiązać? Jak wy to widzicie smile.gif

EDIT: Zmieniłem nazwe tematu, na bardziej adekwatny smile.gif

Napisany przez: marcin96 11.01.2007, 16:41:49

W moim frameworku mam to tak rozwiązane, że każdy widok/akcja może być odpalony z parametrami. ..zatem dla przykladu w akcji, ktora utworzyla nowy news:

  1. <?php
  2.  
  3. function Execute()
  4. {
  5.  [...]
  6.  // kod wewnatrz akcji
  7.  // $rek['ID'] - id ostatniego newsa
  8.  $this->setNext('NewsPlus', 'NewsPlusShow', http://www.php.net/array('newsPlusShow'=>$rek['ID'], 'saved'=>true));
  9.  return true;
  10. }
  11.  
  12. ?>


..normalnie widok NewsPlusShow odpalam z parametrem get newsPlusShow zwierajacym ID rekordu, ktory chce pokazac Tutaj wywoluje ja z parametrem wewnetrznym.. a co robie w samym widoku?

  1. <?php
  2. function Display()
  3. {
  4.  
  5.  $idNews = $this->getParam('newsPlusShow', http://www.php.net/array('get','action'), 'Integer'); // pobieramy ID
  6.  $saved = $this->getParam('saved', 'action', 'Integer'); // dzieki temu moge potem to .tpl przekazac informacje, ze trzeba wyswietlic komun
    ikat o nowoutworzonym news
  7. }
  8. ?>


..dzięki temu w widoku nie obchodzi mnie skąd parametr przyszedł i czemu widok został odpalony (bezpośrednio przez Router, czy w wyniku odpalenia jakiejś innej akcji). Oprócz 'get' i 'action' metoda getParam obsługuje mi też 'post'.

W sumie teraz się zorientowałem, że nie do końca na tym polega Twój problem. Tobie chodzi o tzw łańcuchy akcji. Rozwiązałem to u siebie podobnie jak to zrobił Hawk w swoim Phiend (przynajmniej w Phiend 1 tak było..). Pierwsza akcja jest odpalana rzeczywiście przez router, lecz następne są odpalane jako wynik działania akcji/widoku poprzedniego. Jeżeli nie ma w kolejce żadnych akcji/widoku, to wyświetlam to, co się nazbierało w moim obiekcie Response. Ustawianie następnej akcji odbywa się za pomocą setNext (tak, jak powyżej to pokazałem), które dodaje do kolejki w kontrolerze - posiadam jeden, centralny kontroler w swojej implementacji MVC.

Może to w czymś Tobie pomoże ;>)

Pozdrawiam

Napisany przez: Cysiaczek 11.01.2007, 17:27:31

A co gdyby przenieść sterowanie z kodu do... pliku XML? Spotkałem przykład w książce i zaimportowałem sobie ideę.
Wg. mnie łańcuchy akcji to jedna z bardziej skomplikowanych rzeczy w FW. Przywykłem już patrzeć na akcje jako na uczestników pewnego bardzo rozproszonego systemu.

Moja definicja akcji.
Akcja to podstawowa jednostka w systemie odpowiadająca za wykonanie określonego zadania (model) przy użyciu dostępnych jej bibliotek i funkcji. Wyrózniam dwa podstawowe typy akcji (chyba nie tylko ja):
- prosta
- złożona (kompozyt)

Akcja złożona może składać się z innych akcji wywoływanych w łańcuchu i korzystać z wyników pracy tych akcji. Jej ciało może zostać wykonane na początku łańcucha, na jego końcu (częstszy przypadek) lub po dowolnej z subakcji. Subakcje są wywoływane w pętli przez kontroler i powinny być tak poskładane, żeby w żaden sposób nie mogły doprowadzić systemu do upadku.
Akcja może też przekazać działanie do innej akcji (forward), ale nie sama, a za pośrednictwem kontrolera. Sama ustawia jedynie swój status, który odczytany przez kontroler umożliwia uruchomienie (np. przez header()) kolejnej akcji. Akcja wywołana funkcją forward nie jest częścią łańcucha akcji i stanowi niejako jego przerwanie.
Celem istnienia akcji złożonych jest ponowne wykorzystanie istniejącego kodu poprzez użycie go w niezmienionej formie w innym kontekście. Uff : P

Sorry, że jest tak mądrze napisane, ale może komuś się przyda. Wg. mnie, właśnie to jest esencja wszystkich frameworków - organizacja pracy z kodem i styl programowania. Jako, że aktualnie piszę takie cóś (idzie jak krew z nosa), pozwoliłem sobie na podsumowanie dotychczasowych przemyśleń.

Pozdrawiam.

Napisany przez: menic 11.01.2007, 17:54:44

@Cysiaczek: Zgadzam sie z Toba, ale chyba nie do konca. Nie wiem czy dobrze zrozumiałem twoją definicje forward() Wydaje mi sie ze pomyliłeś z redirect() (głownie przez tenheader()), aczkolwiek moge sie mylić smile.gif A wracając do mojego pierwszego rozwiązania. Wyznaje zasade uproszczenia sobie działań, nawet jesli nie wygląda to profesjonalnie, ważne ze skutecznie i prosto. A o to w koncu w programowaniu chodzi. Do pobierania służą funkcje wbudowane w kontroler. W najczestrzym wypadku tak jak opisałem pobierają one dane na podstawie Routera. Jesli jednak uzyjemy funkcji forward() to w jej ciele ustawiamy recznie akcje. Moze przyklad to lepiej opisze niz moje słowa smile.gif

  1. <?php
  2. public http://www.php.net/static function getModule( $sModule = null )
  3. {
  4. if( $sModule == null )
  5. {
  6. $aUrl = Router::decodeUrl();
  7. if( !http://www.php.net/isset( $aUrl['module'] ) )
  8. {
  9. return _DEF_MODULE;
  10. }
  11. else
  12. {
  13. return $aUrl['module'];
  14. }
  15. }
  16. else
  17. {
  18. return $sModule;
  19. }
  20. }
  21. ?>
  1. <?php
  2. public function forward( $sAction, $sModule = null )
  3. {
  4. Controller::getAction( $sAction );
  5. Controller::getModule( $sModule );
  6. }
  7. ?>

Napisany przez: Cysiaczek 11.01.2007, 18:19:55

Przez forward rozumiem uruchomienie innego łańcucha akcji. Ok. za mnie niech przemówi XML : )

  1. <index>
  2.      <status>
  3.            <ok>
  4.                  <view>index</view>
  5.            </ok>
  6.            <error>
  7.                  <forward>error</forward>
  8.            </error>
  9.      </status>
  10.  
  11.      <subactions>
  12.            <news />
  13.            <menu />
  14.      </subactions>
  15. </index>
  16.  
  17. <news>
  18.      <status>
  19.            <ok>
  20.                  <view>news</view>
  21.            </ok>
  22.            <error>
  23.                  <view>error</view>
  24.            </error>
  25.      </status>
  26. </news>
  27.  
  28. <menu>
  29.      <status>
  30.            <ok>
  31.                  <view>listmenu</view>
  32.            </ok>
  33.            <error>
  34.                  <view>error</view>
  35.            </error>
  36.      </status>
  37.  
  38. </menu>
  39.  
  40.  
  41. <error>
  42.      <status>
  43.            <ok>
  44.                  <view>ErrorPage</view>
  45.            </ok>
  46.            <error>
  47.                  <exit>Blad krytyczny</exit>
  48.            </error>
  49.      </status>
  50.  
  51.      <subactions>
  52.            <logError />
  53.            <sendNotify />
  54.      </subactions>
  55. </error>




W powyższym przykładzie wywołując akcję index wywołujemy subakcje
<news />
<menu />
W razie powodzenia zostaną wybrane odpwiednie widoki i system jakoś sobie dalej poradzi. W razie błędu kontroler uruchomi nowy łańcuch, czyli akcję <error />. To, czy zrobi to przez header, czy nie, jest kwestią drugorzędną. Faktycznie można uznać, że mój forward to coś w rodzaju redirect i chyba można stosować zamiennie ta nazwę : )
powyższy przykład nie uwzględnia oczywiście modułów (bo i po co - to przykład)
Twoja metoda forward() to u mnie ekwiwalent execute(). Akcja go nie ustawia.
Jeszcze pokażę akcję.
  1. <?php
  2. class Index extends Action {
  3.  
  4. public function Perform(){
  5. $test=1;
  6. // tak poglądowo
  7. $this->aVars['tekst']="jakiś tekst";
  8. $this->aVars['lista']=$array;
  9.  
  10. if ($test==1){
  11. $this->setStatus("ok");
  12. }
  13. else {
  14. $this->setStatus("error");
  15. }
  16.  
  17. }
  18.  
  19. }
  20. ?>


Pozdrawiam

Napisany przez: menic 11.01.2007, 19:19:43

Kod który przedstawiłem dla funkcjiforward jest szczątkowy. Chodzi tylko o ukazanie głownego problemu jakim jest "dobieranie" sie do informacji jaki jest aktualny moduł i akcja winksmiley.jpg Forward własciwie jest tylko funkcją dostępową do zmiennych prywatnych smile.gif Ustawia on odpowiednie zmienne w klasie i metoda executeAction wywołuje akcje i nastepnie widok dla tej akcji. Całośc znajduje sie w klasie AppController. Tak więc mamy: Controller -> AppController->View && Action. Tak to wygląda w uproszczeniu.

Ciekawie prezentuje sie to drzewo xml. Mogłbyś napisać coś wiecej snitch.gif

Zastanawia mnie jeszcze jedno pytanie. Jak najskuteczniej wywołać kilka akcji wraz z widokami w jednej akcji? Troche namieszałem. Dajmy przyklad:

  1. <?php
  2. class DefaultAction extends View
  3. {
  4. public function Index()
  5. {
  6. $this->newModel( 'Index', 'Test');
  7. $this->newModel( 'Info', 'Modul');
  8. }
  9. }
  10. ?>
Najspierw wywołujemy akcje Index() w module Default. W tej akcji wywołujemy 2 nowe akcje. Czyli wywołując jedną akcje otrzymujemy ich aż 3. Kiedyś sie nad tym męczyłem jak tworzyłem CMSa, ale nic ciekawego nie wymysliłem. Teraz po przejsciu na OOP chce to już rozwiązać. Przydatne jest to w sytuacji kiedy mamy moduł newsy oraz moduł komentarze. Wywołujemy akcje showNews i w tejże akcji wywołujemy akcje ShowComments z Modułu komentarze. Oczywiscie mozna przekazywać parametry do akcji ShowComments z wnetrza ShowNews takie jak id komentarza itp. Na przeszkodzie stoi mi tylko połączenie wyświetlania szablonów. Bo jest to zrobione, że mamy głowny szablon strony z całym szkieletem w którym jest $this->LoadView(). LoadView załaduje nam podszablon dla danej akcji i modułu. Wszystko działa bardzo ładnie dla pojedynczego wywołania akcji bądź dla forward. Natomiast nie wiem jak to rozwiązać dla większej ilości.
[EDIT] Męcze sie już nad tym pare godzin, aby wywołać klilka akcji w jednej. Prawie mi sie udało, tylko jest jeden problem. Nie wiem jak "złączyć" akcje z widokiem w taki sposób aby widok mógł sie odwołać tylko do zmiennych z jego akcji. Bo w tym do czego doszedłem, widok "gubi" $this. Czy jest jakiś sposób aby "połączyć" obiekty? Przyklad:
  1. <?php
  2. $o = new Obiekt1
  3. $o->funkcja();
  4.  
  5. $o = new Obiekt2; //Zeby Obiekt2 "dołączył" sie do Obiekt1
  6. $o->Innafunkcja();
  7. ?>

Jest coś podobnego mozliwe? Albo może kto ma jakiś złoty środek? Ja juz nie mam pomysłow worriedsmiley.gif

Napisany przez: Cysiaczek 12.01.2007, 09:25:23

Najlepszy moim zdaniem (ale do średnich i dużych) projektów jest wzorzec http://www.martinfowler.com/eaaCatalog/twoStepView.html, który zakłada najpierw rendering mniejszych widoków, a potem ich połączenie w całość.
Jeśli spojrzysz na XML, który dałem wyżej, to zobaczysz znaczniki <view>nazwa</view>. To są właśnie widoki, które będą renderowane. W tym drzewie pominąłem część znaczników, więc nie ma np, znacznika <viewFrame>nazwa</viewFrame>, który jeśli akcja jest wywoływana żądaniem (nie jest subakcją), stanowi schemat łączenia poszczególnych mniejszych widoków. W prezentowanym przykładzie, jeśli wszystko pójdzie dobrze, to akcja Index będzie miała do dyspozycji aż 3 widoki
news.tpl
menulist.tpl
index.tpl

oraz schemat łaczenia index.frame.tpl

news.tpl (pseudo-kod)

  1. <? http://www.php.net/print $news['title']; ?>
  2. <br>
  3. <? http://www.php.net/print $news['body']; ?>


index.frame.tpl
  1. <html>
  2. <head></head>
  3. <body>
  4. <div>
  5. <? AHelper->get("menu"); ?>
  6. </div>
  7. <div>
  8. <? AHelper->get("news"); ?>
  9. </div>
  10. </body>
  11. </html>


Metoda get() przyjmuje jako parametr nazwę akcji i dołącza aktualny widok tej akcji (wybrany przez kontroler na podstawie statusu zgłoszonego przez akcję) z pliku XML. Oczywiście każdy widok ma dostęp tylko do danych, które wygenerowała jego akcja (wewnątrz metody get()). Wydaje mi się, że właśnie o taki złącznik Ci chodzi, tak?

Pozdrawiam.

Napisany przez: menic 12.01.2007, 12:05:12

Nie wiem czy sie rozumiemy do konca.
Widok jest podzielony na szablon głowny:

  1. Witamy na stronie Sparkle Works :)<hr><br>
  2.  
  3. <?php
  4. $this->loadModuleView();
  5. ?>
  6.  
  7. <br><br><br><br><br><br>
  8. <hr>
  9. Powered by Sparkle
oraz Szablon akcji. Metoda loadModuleView() to poprostu include('szablonAkcji.php); I to nad czym sie aktualnie męcze to jak zrobić aby przy wywołaniu Akcji ShowNews jednoczesnie wywołać ShowComments, bez ingerencji w głowny szablon. Kawałek kodu z AppController:
  1. <?php
  2. public function executeAction( $sAction, $sModule, $a = '' )
  3. {
  4. //echo 'Action'. $sModule;
  5. $sTempModule = $sModule.'Action';
  6. $this->oModule = new $sTempModule;
  7. $this->oModule->$sAction();
  8.  
  9. $t = $this->s($this->oModule, $sAction, $sModule);
  10.  
  11. if(http://www.php.net/is_array(self::$om))
  12. {
  13. include(_SPARKLE_PATH.'/app/'._SPARKLE_APP.'/modules/'.self::$om['mod'].'/action/Actions.class.php');
  14. $this->oModules = new TestAction;
  15. $this->oModules->Index();
  16. }
  17. $this->oModule->loadAppView($this->oModule);
  18. //echo self::$om;
  19. }
  20.  
  21. public function newModel( $sAction, $sModule = null )
  22. {
  23. include(_SPARKLE_PATH.'/app/'._SPARKLE_APP.'/modules/Test/action/Actions.class.php');
  24. $o = new TestAction;
  25. $o->Index();
  26. //$this->s($o, $sAction, $sModule);
  27. }
  28. ?>
Nie przejmujcie sie bałaganem, gdyż to tylko testy winksmiley.jpg I wszystko jest prawie pwisane na sztywno. Plik Action wyglada tak:
  1. <?php
  2. class DefaultAction extends View
  3. {
  4. public function Index()
  5. {
  6. $this->d = 'sssssdszzzzzzzzzzzzzzz<br>';
  7. //$this->test = 'duuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuupa';
  8. //echo '<br>ddddddddddddddddddddddddddddddddddddd';
  9. $this->newModel( 'Index', 'Test');
  10. }
  11. }
  12. ?>
I to własnie on jest wywołany w przegladarce. Wenatrz akcji index wywołujemy moduł Test, z akcją Index. To jakoś działa. Tylko niestety wszystko sie pipeprzy w
  1. <?php
  2. $this->oModule->loadAppView($this->oModule);
  3. ?>
Przez takie wywołanie gubie referencje w szablonie do Obiektu $this->oModules. I wszelkie zmienne zadeklarowane w Module test w akcji index, nie zostaną wyswietlone w szablonie. Jak temu zaradzić? sadsmiley02.gif sad.gif

Napisany przez: Cysiaczek 12.01.2007, 12:45:59

Wprowadź obiekt kolekcji uruchamianych modułów. Przy próbie inicjalizacji nowego modułu, referencję wywołującego umieść najpierw w kolekcji, a dopiero potem wywołaj nowy.

  1. <?php
  2. $collection->registerModule($this);
  3. $this->newModel( 'Index', 'Test');
  4. ?>


Potem jak potrzebujesz danych z modułu, to pobieraj go z kolekcji.
  1. <?php
  2. $module=$collection->getModule($moduleName);
  3. // albo konkretnie
  4. $this->oModule->loadAppView($collection->getModule($this->oModule));
  5. ?>


Pozdrawiam.

Napisany przez: menic 12.01.2007, 15:34:55

Nie za bardzo rozumiem. Obiekt kolekcji? Co to sad.gif

Napisany przez: Cysiaczek 12.01.2007, 16:16:54

Obiekt, który coś przechowuje i pozwala na przeglądanie tego oraz zarządzanie itp. W najprostszym przypadku może to być tablica, ale obiekt daje więcej możliwości.

Pozdrawiam.

Napisany przez: Turgon 12.01.2007, 16:58:10

Czyli na polskie tłumacząc napisz sobie rejestr ;]
Co do widoków używam ten wzorzec co podał Cysiaczek proste i wygodne ;] .

Napisany przez: menic 12.01.2007, 20:25:31

Ufff....
Już sie uporałem, bez rejestru winksmiley.jpg Troche pokombinowałem z referencjami do obiektów i działa guitar.gif
Narazie to tylko światełko w tunelu, bo większość rzeczy wpisałem na sztywno, ale to już poprawki kosmetyczne smile.gif Aby nie myliły sie zmienne w szablonach, tzn aby nie została wykorzystana przez przypadek zmienna z akcji pierwszej w szablonie drugim zrobiłem małe myku snitch.gif Tzn. Zamiast w szablonach odwolywac sie do zmiennych przez

  1. <?php
  2. $this->zmienna
  3. ?>
robimy tak:
  1. <?php
  2. $NazwaModulu->zmienna
  3. ?>
W ten sposób mamy wszystko odzzielone w szablonach. Natomiast w akcjach uzywamy normalnie $this->zmienna smile.gif Jednak mój sukces nie kończy dyskusji Rkingsmiley.png

Turgon: Mógłbys troche szerzej opisać ten "wasz" wzorzec widoków biggrin.gif

Napisany przez: Turgon 14.01.2007, 10:43:49

Tzn. tak ;]

Np. mam newsy i podpinam tam obiekt view. Renderuje sobie do zmiennej po kolei każdego. Podaje je szablonowi newses, który je listuje i znowu do zmiennej. Potem ta zmienna dopiero wędruje do szablonu index i tam jest wyświetlana razem z nim.

Napisany przez: menic 14.01.2007, 12:06:53

Czyli zawartość szablonu news wczytujesz do zmiennej zamiast includowac szablon? Zgadza sie?

Napisany przez: Turgon 14.01.2007, 20:12:44

Tak ;] To jest wygodne i szybkie smile.gif Tak jest np. w CI

Napisany przez: Cysiaczek 14.01.2007, 20:23:16

Ja z kolei includuję : )

Napisany przez: menic 14.01.2007, 20:45:38

Cytat(Turgon @ 14.01.2007, 20:12:44 ) *
Tak ;] To jest wygodne i szybkie smile.gif Tak jest np. w CI

Wygodne to napewno smile.gif Ale czy szybkie... Include szybsze guitar.gif

Napisany przez: Turgon 14.01.2007, 22:07:23

menic: Bez różnicy ;] Sprawa gustu przedewszystkim winksmiley.jpg

Napisany przez: menic 14.01.2007, 22:12:06

W praktyce, podejrzewam jest niewielka róznica jesli chodzi o wydajność. Ale jeśli chodzi o wygode to jak najbardziej. Gdybym u siebie tak zrobił to nie męczyłbym sie tyle z ładowaniem akcji itp. Ale no wlasnie... Kwestia gustu winksmiley.jpg
A co do moich akcji i widoków to już chyba skonczyłem skończyłem biggrin.gif Właściwie zrobiony jest już cały Controller, AppController, oraz View. smile.gif Sporo sie męczyłem z forward'em i załadowaniem akcji w akcji, ale w koncu sie udało. Było warto poświęcic tyle czasu. Mam tylko nadzieje, że nie odbije sie to negatywnie na zaliczeniach, które mam w tym tygodniu winksmiley.jpg

Napisany przez: widmogrod 15.01.2007, 15:05:08

Witam, zaprezentuje moje rozwiązanie tego problemu

posiadam plik konfiguracyjny bloków np:

  1. <block>
  2. <default>
  3.    <layout>index.tpl<layout>
  4.    <blocks>
  5.         <main controller="index" action="index" />
  6.         <info controller="index" action="info" />
  7.    </blocks>
  8. </default>
  9. <login>
  10.    <layout>login.tpl<layout>
  11.    <blocks>
  12.         <main controller="login" action="index" />
  13.    </blocks>
  14. </login>
  15. </block>


default - są zdefiniowane domyślnie odpalane bloki i szablon który ma je wykorzystać
login - jak wyżej ..

z odpaleniem default nie ma problemu ( odpalany domyślnie ) ale teraz jak odpalić login otóż posiadam aliasy na rutera które definiują w sobie odpalane bloki przykład pliku konfiguracyjnego aliasów
w szablonie wykorzystuje je w następujący sposób

  1. <alias>
  2.    <login controller="logowanie" action="main" block="login"/>
  3. <alias>


w kontrolerze definiuje "łapanie" bloków poprzez metode setBlock() np.

  1. <?php
  2. class indexAction extends AController
  3. {
  4. public function index(){
  5. $view = $this->getView();
  6. $this->setBlock('main', $view->parse('index/main.tpl');
  7. }
  8.  
  9. public function info(){
  10. $view = $this->getView();
  11. $view->infoMSG = 'jakaś informacja';
  12. $this->setBlock('info', $view->parse('index/info.tpl');
  13. }
  14. }
  15.  
  16. class logowanieAction extends AController
  17. {
  18. public function main(){
  19. $view = $this->getView();
  20. $this->setBlock('main', $view->parse('logowanie/main.tpl');
  21. }
  22. }
  23. ?>


i wykorzystuje je w szablonie głównym poprzez taką linijkę
  1. <?php http://www.php.net/print $this->block->main?>


... mam nadzieje że przedstawiłem to w miare zrozumiale ..

PS1. moim zdaniem definiowanie odpalanych bloków w akcji jest delikatnie chybione, bo gdy chcemy wzbogacić widoko jakieś dodatkowe bloki trzeba przeszukać klasy akcji i je zmodyfikować, a trzymając to w jednym nie pogubimy się przy większych projektach ..

PS2. można też zrobić pomocnika dla widoku który odpala odpowiednie akcje tj ..
  1. <?php http://www.php.net/print $this->block->run('index', 'main');?>

wtedy zabawa nie jest już tak hardkorowa z plikami konfiguracyjnymi ... ale czy jest to zgodne z MVC questionmark.gif co o tym sądzicie ..

Napisany przez: menic 15.01.2007, 18:21:25

Szczerze? Nie rozumiem o czym piszesz blink.gif Co masz pod pojęciem bloki. Bo dla mnie to kawałek kodu php i html umieszczane w glownym layoucie strony, raczej nie mający powiązań z akcjami.

Napisany przez: widmogrod 15.01.2007, 19:56:23

u mnie bloki są wynikiem akcji ..

Po sparsowaniu xml'a (z poprzedniego postu) mam tablice, która zawiera nazwy bloków z kontrolerem i akcją do odpalenia. Wrzucam to do ActionChain i ruszam z tym w FrontControllerze razem z wynikiem rutera.
Każda z odpalonych akcji umieszcza swój wynik w odpowiednim bloku poprzez

  1. <?php
  2. $this->setBlock('mojBlok', 'trescBloku');
  3. ?>


teraz tak zcachowany widok akcji wywalam do szablonu poprzez

  1. <?php
  2. http://www.php.net/print $this->block->mojBlock;
  3. ?>


Mam nadzieje ze sprostowałem nazwe "bloki" w moim FW ..
Ps. rzeczywiście delikatnie odskoczyłem od wątku dry.gif ... jednak jedną akcja z url'a np. index.php/news/show/2 jestem w stanie jednocześnie odpalić akcje komentarzy do tej akcji i bez problemowo połączyć je w jednym szablonie winksmiley.jpg ..

jak za bardzo namieszałem w wątku z góry przepraszam

Pozdrawiam
widmogrod

Napisany przez: menic 15.01.2007, 20:58:03

Smieszne masz nazewnictwo wszystkiego. U mnie sa tylko dwa kontrolery: Controller oraz AppController. Ten pierwszy znany jest jako FrontController. Dalej jest moduł i akcja z widokiem. U ciebie kazdy moj moduł to jest nowy kontroler :roll2: Ale wracajac do tematu...
Ja nie musze nic edytować, dopisywac do szablonu. Nic z tych rzeczy. Kazdy kazda akcja modułu ma swoj tpl które są ładowane do głownego tpl

  1. <h1>Witamy na stronie Sparkle Works :)</h1><hr><br>
  2. <pre>
  3. </pre>
  4.  
  5. <?php
  6. $this->loadModuleView();
  7. ?>
  8. <br><br><br><br><br><br>
  9. <hr>
  10. Powered by Sparkle
Kazdy wynik akcji bedzie w loadModuleView().
Natomiast w samej akcji moge zrobić nawet cos takiego:
  1. <?php
  2. class DefaultAction extends View
  3. {
  4. public function Index()
  5. {
  6. //$this->redirect( 'Show', 'News', Array( 'type' => 'get', 'id' => 77 ) );
  7. //echo 'forward<br>';
  8. $this->forward('Show', 'Default'); //Przekieruje do modułu Default do akcji Show nie wyświetlając wyniku aktualnej akcji
  9. $this->newModel( 'Show', 'News' ); //Załaduje akcje Show z modułu News wraz z widokiem
  10. $this->newModel( 'Show', 'Test', http://www.php.net/array('id' => 77, 'type' => 'get') );  //Załaduje akcje Show z modułu test wraz z parametrami oraz widokiem
  11. }
  12. }
  13. ?>
Natomiast jesli forward() damy na koncu to zostaną wykonane wczesniejsze załadowane akcje, ale bez ładowania widoków Rkingsmiley.png Tak wiec mozliwosci kombinowania jest dużo guitar.gif I jak zechce to moge odpalic nawet kilka razy ta samą akcje (tylko nie wiem po snitch.gif )

Napisany przez: widmogrod 15.01.2007, 23:22:03

Cytat
Smieszne masz nazewnictwo wszystkiego. U mnie sa tylko dwa kontrolery: Controller oraz AppController.

Zwał jak zwał .. funkcje są podobne AForntController - jest to "rozrusznik" zaczyna wszystko i AController - jest to abstrakcja akcji .. u ciebue View, widze ze posiada metode forward() co pasuje mi bardziej do akcji niż do widoku ale to jest kwestia podejścia programisty do projektowania FW i nazewnictwa .. no chyba ze dziedziczony View nie posiada forwarda ... i ma całkiem inne zadanie .. możesz mi powiedzieć jakie cechy ma klasa View?

Powiem ze ciekawe rozwiązanie .. jednak zostane przy swoim .. a zawsze mogę wyposażyć FW w metode

  1. <?php
  2. $wynik = $this->runAction('controller', 'action', 'params');
  3. ?>
( takie rozwiązanie jest chyba w symfony .. nie jestem 100% pewien .. )

która bedzie mi zwracać wynik akcji z innego kontrollera ect. i później
  1. <?php
  2. $view->set('main', $wynik);
  3. ?>


i w szablonie

  1. <?php
  2. http://www.php.net/print $main;
  3. ?>


i podobny efekt, co o tym sądzisz?

Napisany przez: arecki 16.01.2007, 00:20:00

Przyglądam się Waszej i snuje wnioski i pomysły smile.gif. Wnioski takie mam, że albo lubicie sobie komplikować sprawę albo po prostu 'tak Wam wygodnie'. Oczywiście każdy ma to co lubi i pisze FW dla siebie i pod siebie. Z resztą sam też się w to bawię i więcej mam przyjemności z budowy FW niż z samego korzystania z niego smile.gif.

Co do wywoływań akcji to akurat ja sobie to zupełnie inaczej obmyśliłem. Wydaje mi się że sporo prościej ale po kolei wytłumaczę. Generalnie jest sobie kontroler. Ma on funkcję statyczną runEvent() z parametrami : jaką klasę i metodę wywołać oraz jakie parametry przesłać do niej. Zwraca to co dana metoda wypluje. Oczywiście sam kontroler ma w sobie mechanizmy sprawdzające czy się wywołania nie zapętlą itp. Ma również obiekty odpowiadające za cache'owanie obiektów akcji (czy jak ja to nazywam 'eventów'), za dane sesji no i za widok.

Metodę runEvent można wywołać z każdego miejsca FW tak więc odpada nam konieczność robienia forward() i martwienia się o to czy można i jak. Dodatkowo daje nam możliwość kontrolowania kazdej akcji z poziomu kontrolera (chyba zamieszałem:) ). Każda klasa obsługująca zdarzenia musi dziedziczyć po bazowej klasie do zdarzeń. Dzięki temu każda z akcji ma możliwość dodania zmiennych wyświetlanych w widoku czy modyfikacji zmiennych sesyjnych. Dopiero później kontroler przekazuje do widoku sterowanie z zebranymi danymi. Jedyne co akcja musi zrobić to zdefiniować nazwę szablony do wyświetlenia i tylko ta akcja która została wywołana z router'a. Dodatkowo mam możliwość zdefiniowania czy daną akcję mogę wywołać przez URL'e czy tylko i wyłącznie przez metodę runEvent.

Jedyne co mnie natchnęliście to muszę się zastanowić czy chcę aby klasy obsługujące zdarzenia miały możliwość definiowania własnych części widoku a nie tylko danych do wyświetlenia.

Napisany przez: menic 16.01.2007, 07:50:54

View dziediczy po AppControlerze, stąd dostepnośc forward. W Klasie View trzymane są metody jak nazwa wskazuje do widoku, takie jak loadModuleView(), loadAppView(), setView() itp. Narazie jeszcze jest nie rozubudowana, gdyz meczyłem sie z kontrolerami smile.gif

CZy to komplikowanie? W pewnym sensie tak, ale zalezy jak na to pparztec winksmiley.jpg Pisze o głownie dla pożniejszej wygody. Wkurzyło mnie jak pisałem w Symfony, ze w module newsów musze pisac tez moduł komentarzy (wiec po co cała modułowosc?) dry.gif
U mnie Controller odpowiada tylko za załadowanie odpowiednich plikow i tyle. Reszte przejmuje appController z funkcjiami do ładowania akcji itp. Metoda NewModel() to jest tak jak by nakladka na metode executeAction() z appControllera. Musiałem rozdzielic, bo raczej rzadko sie uzywa newModel wiec bez sensu byłoby to pakowanie do głownej metody wywoławczej smile.gif
A działanie forward jest takie, ze wykonuje wszystko w danej akcji, lecz nie wyswietla jej wyniku tylko przenosi do innej akcji i tam juz wyswietla wynik tej przeniesionej biggrin.gif

Napisany przez: widmogrod 16.01.2007, 13:42:02

@menic - i już wszystko jasne ( ciekawe podejście smile.gif) ..

Cytat
Z resztą sam też się w to bawię i więcej mam przyjemności z budowy FW niż z samego korzystania z niego

hehe .. z tym sie zgodze biggrin.gif

Każdy ma swoje podejście do projektowania i dla mnie takie rozwiązanie jest bardziej przyjemne .. jednak ciągle się rozwijam i kto wie czy za miesiąc nie będę miał nowej wizji rozwiązania tego problemu .. czy też innych

Pozdrawiam
Miłego kodowania

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)