![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 99 Pomógł: 15 Dołączył: 15.11.2007 Skąd: Nowogród Bobrz. Ostrzeżenie: (0%) ![]() ![]() |
Zastanawiam się, czy to co zrobiłem można zrobić lepiej.
Otóż - mam stronę, na której chcę wyświetlić pewną ilość rekordów. Strona ma się wyświetlić raz, natomiast kolejne porcje rekordów chcę pobierać w tle. Tworząc to proceduralnie mam zawartość "porcji" rekordów razem z kodem, który je pobiera w osobnym inkludzie. Próbując zrobić to w FW wymyśliłem sobie 2 osobne akcje kontrolera - główna (index()) podczas odczytywania strony wywołuje drugą akcję, odpowiedzialną za pobranie określonej porcji rekordów (nazwałem ją best()). Poniższy kontroler działa, ale mam wrażenie, że nie jest to całkowicie poprawnie zrobione, dlatego proszę o jakieś sugestie ze strony zaawansowanych "kohanowców". Oczywiście nie patrzcie na sam pager, który jest tu wstawiony tylko roboczo. Szczególnie mnie drażni ta sztuczka z zamianą nazwy akcji na linku (wówczas przy wyłączonym JS będzie wywoływać /index.php/ipeop/index/X a AJAX'em: /index.php/ipeop/best/X, czyli bezpośrednio akcję "best"). Poza tym rozpoznawanie, czy wywołanie jest zwykłe czy Ajaxowe też jest takie na siłę, bo nie bardzo wiem jak skorzystać z request::is_ajax() - pewnie trzeba jakimś helperem robić linki, ale czy da się wówczas korzystać z advAJAX? A nic więcej niż advAJAX nie jest mi potrzebne. Kod <?php defined('SYSPATH') or die ('None shall pass!');
class Ipeop_Controller extends Website_Controller { //domyślna akcja public function index($page=1) { $this->template->header = new View('elements/header'); $this->template->header->title = 'Osoby!!'; $this->template->best_div = $this->best($page, FALSE); } //pobranie porcji rekordów public function best($page=1, $render = TRUE) { $best = new View('_best'); $best->title = 'Najlepsze osoby'; if ($render) { $best->ajax = 1; $this->auto_render = false; } $limit_start = ($page-1)*5; $result = $this->db->query('select count(id_user) as c from nfv_active_users')->result(FALSE); $n= $result[0]['c']; $pages = $n / 5; $osoby = $this->db->query('select * from nfv_active_users '.$limit_start.', 5'); $best->osoby = $osoby->result(FALSE); $link = '<a onclick="advAJAX.get({url: this.href.replace(\'/index/\', \'/best/\'), tag: \'5best\'}); return false;" href="/index.php/ipeop/index/%d">%s</a>'; $pager = 'Ilość: '.$n.' '; if ($page > 1) { $pager .= sprintf($link, $page-1, '<<'); } if ($page < $pages) { $pager .= sprintf($link, $page+1, '>>'); } $best->link = $pager; return $best->render($render); } } |
|
|
![]()
Post
#2
|
|
Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Moje rady:
- Pagination - możliwe, że request::is_ajax() nie działa przy advAjax z powodu braku odpowiedniego nagłówka. Podobny przypadek miałem przy chwilowym używaniu mintAjax. Po powrocie na MooTools / jQuery sprawdzanie wywołania ajaxowego działa bez zastrzeżeń. Nie jest to więc wina Kohany tylko samego advAjax. - do tworzenia linków używaj html::anchor i wywal kod tworzący link z kontrolera do widoku. - dobrze Ci radzę: korzystaj z modeli. Pakowanie zapytań do bazy wprost do kontrolera jest naprawdę nieeleganckie... Po to masz w Kohanej MVC żeby z niego korzystać. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 99 Pomógł: 15 Dołączył: 15.11.2007 Skąd: Nowogród Bobrz. Ostrzeżenie: (0%) ![]() ![]() |
Co do pierwszej i ostatniej rady - zarówno pager jak i pobieranie danych jest tutaj wciśnięte tylko tymczasowo. Chodzi tylko o rozpracowanie problemu współpracy tych dwóch akcji ze sobą i z advAJAX'em (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Co do nagłówka - faktycznie! Po przyjrzeniu się w FireBugu jakie nagłówki są wysyłane, okazało się, że nie jest wysyłany 'X-Requested-With: XMLHttpRequest' a po nim właśnie odbywa się rozróżnianie wywołań ajax/nie-ajax. Dołożyłem w kodzie biblioteki advAJAX taki nagłówek i ten aspekt już jest załatwiony (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) To teraz mogę spróbować przerobić ten kontroler, aby się odpowiednio zachowywał w zależności czy z ajaxa czy bez. Heh, udało się zmienić advAJAX i korzystać z request::is_ajax(). Udało się też zrobić wszystko w jednej akcji kontrolera. Zastosowałem też html::anchor do generowania linków. Wygląda to teraz tak (znów - nie patrzymy na część pobierającą dane (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) ): Kod <?php defined('SYSPATH') or die ('None shall pass!'); class Ipeop_Controller extends Website_Controller { //domyślna akcja public function view($page=1) { // !!! Tymczasowo pobieranie danych i paginacja tutaj (IMG:http://forum.php.pl/style_emoticons/default/exclamation.gif) ! $limit_start = ($page-1)*5; $result = $this->db->query('select count(id_user) as c from nfv_active_users')->result(FALSE); $n= $result[0]['c']; $pages = ceil($n / 5); $query = $this->db->query('select * from nfv_active_users_by_name limit '.$limit_start.', 5'); $osoby = $query->result(FALSE); //pager $onclick = 'advAJAX.get({ url: this.href, tag: \'5best\' }); return false;'; $link = 'ipeop/view/%d'; $pager = 'Ilość: '.$n.'; strona '.$page.' z '.$pages.' '; if ($page > 1) { $pager .= html::anchor(sprintf($link, $page-1), '<<', array('onclick'=>$onclick)); } if ($page < $pages) { $pager .= html::anchor(sprintf($link, $page+1), '>>', array('onclick'=>$onclick)); } // zasadnicza część kontrolera if (request::is_ajax()) { //jeśli ajaxowe, to wyświetl tylko _best $ipeop = new View('_best'); $ipeop->osoby = $osoby; $ipeop->pager = $pager; $this->auto_render=false; //wyłączenie auto renderowania szablonu $ipeop->render(true); } else { //pomocniczy widok _best $best = new View('_best'); $best->osoby = $osoby; $best->pager = $pager; $this->template->best_div = $best->render(); $this->template->header = new View('elements/header'); $this->template->header->title = 'Osoby!!'; } } } Ale nurtuje mnie jedna kwestia i gdyby ktoś zechciał wrzucić szablon rozwiązania, to byłbym wdzięczny. Mianowicie zdarza się, że mam stronę z kilkoma dynamicznie pobieranymi elementami. Logicznie by było mieć każdy z nich w osobnej akcji - tylko jak to wywoływać?? Czyli wg schematu: Przy pierwszym wywołaniu strony: Szablon strony -> element A -> element B -> ... A potem na linku odświeżania elementu A wywołanie tylko akcji A, dla elementu B - tylko akcji B itp. Oczywiście będzie ciężko zrobić taką stronę, żeby działała bez włączonego JS, ale to na razie nieważne. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 24.08.2025 - 20:38 |