Artykuły jmail's software

CakePHP i AJAX

by on Jan.16, 2012, under Java Script, PHP / CF / .NET / Java

Tworzę aplikację na potrzeby swojego klienta. Taki intranecik gdzie klient może sobie zarządzać swoimi placówkami w sensie tworzyć nowe w odpowiednich lokalizacjach a one napychają mu później dane sprzedażowe ze swojego programu poprzez plik XML. Już kilkakrotnie podchodziłem do tematu połączenia AJAX’a z Cake’iem ale zazwyczaj się kończyo w jakiś masakryczny sposób a wszelkie podane sposoby wymagały albo konkretnego jQuery albo Bóg wie jakiej logiki po stronie aplikacji.

Robiąc aplikacje w ColdFusion natknąłem się na możliwości jakie w tym zakresie daje mój ulubiony framework – CFWheels – http://cfwheels.org/docs/1-1/chapter/wheels-ajax-and-you

Czy to nie jest coś wspaniałego? Dajesz jaki format chcesz mieć i albo wypluwasz to w postaci HTML przez odpowiedni widok, albo ładujesz jako typowego JSON’a. Wracając jednak do Cake’a bardzo mi tego brakuje… Wiem, wiem. Ostatnio jakieś pierwiosnki się pojawiły, że niby w 2.1 czy nawet już w 2.0.5 da się to zrobić. Nie sprawdzałem. 2.1 jest w wersji nieprodukcyjnej, więc nie zaproponuję klientowi, a 2.0.5 tak szybko jakoś wyszło, że nawet jeszcze z 2.0.4 nie zdażyłem się zaprzyjaźnić.

Mimo wszystko jednak doskwiera mi brak takiego rozwiązania i postanowiłem to zmienić. Przeanalizowałem wszystko i wyszło mi, że najprościej będzie w ogóle nie polegać na funkcjach z Cake’a tylko zbuduję sobie sam takie rozwiązanie. Jak już podjąłem decyzję to poszło bardzo, ale to bardzo szybko….

 

Zaczynam od strony aplikacji (JavaScript). Oczywiście zostało tu wykorzystane jQuery, które najłatwiej zezwoli na wywołanie. Jak w jQuery wygląda wywołanie AJAX’owe? O tak:

 

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
     url: "jakisUrl"
     ,async: true
     ,dataType: "html"
     ,type: "POST"
     ,data:{}
     ,success: function(data){
     }
     ,error: function (xhr, ajaxOptions, thrownError){
     }
 });

No to już jest jakaś solidna podstawa

Czy z tego da się już załadować AJAX’a? Pewnie, że się da. Ubierzmy to szybko w funkcję:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function loadAJAXFromCake(url,data = null, success='', error=''){

    $.ajax({
     url: url
     ,async: true
     ,dataType: "html"
     ,type: "POST"
     ,data:{data}
     ,success: function(data){
               eval(success+'('+data+')');
     }
     ,error: function (xhr, ajaxOptions, thrownError){
               eval(success+'('+data+')');
     }
     });
}

Świetnie – po stronie przeglądarki sprawę mamy załatwioną – chyba wszyscy wiedzą jak to wywołać?. Ale co z CakePHP? Tu jest sprawa trochę bardziej skomplikowana.

Załóżmy, że przez AJAX chcemy wywołać akcję: controller => ‘user’ action => ‘lists’;

Więc w kontrolerze UserController musimy stworzyć akcję lists – załóżmy, że to ma zwóić jakiś message

1
2
3
4
5
    public function lists(){
        error_reporting(0); //dla zachowania czystości, żeby na pewno nic nie  wyplute zostało
        $this->set('message', 'Jakiś message');
        $this->set('vars_to_compact', array('message'));
    }

Wszystko jasne? Najpierw ustwiamy do widoku naszą zmienną message i ustawiamy tablicę zmienny, które będziemy przesyłać. Teraz stworzymy widok, ale nie dla tej funkcji (po co? wszystkie takie wywołania mogą krozystać z jednego widoku :) ). Tworzymy widok w /View/Elements/ajax_output.ctp i mamy w nim

1
    <%=json_encode(compact($vars_to_compact));%>

Co to zrobi? No wszystko to o co nam chodzi. Najpierw skompaktuje wszystkie wymienione dane do jednej tablicy a później zamieni je na format JSON. No tak, ale jeszcze brakuje dwóch rzeczy w PHP. Teraz funkcja jest kompletna:

1
2
3
4
5
6
7
    public function lists(){
        error_reporting(0); //dla zachowania czystości, żeby na pewno nic nie  wyplute zostało
        $this->set('message', 'Jakiś message');
        $this->set('vars_to_compact', array('message'));
        $this->layout = '';
        $this->render('/Elements/ajax_output');
    }

Na koniec jeszcze ciekawostka. Dlaczego w funkcjo JavaScript jest użyty format HTML? Już tłumaczę. Problem jest taki, że CakePHP zwraca wszystkie dane po jednej linii wolnej. Nie mam bladego pojęcia z czego to wynika. Może ja coś robię, ale nie mam czasu tego szukać, więc zrobiłem w taki sposób jak wcześniej pokazałem. Dlatego teraz brakuje w funkcji JS jednej rzeczy, żebyśmy mogli się cieszyć otrzymanym formatem JSON.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function loadAJAXFromCake(url,data = null, success='', error=''){

    $.ajax({
     url: url
     ,async: true
     ,dataType: "html"
     ,type: "POST"
     ,data:{data}
     ,success: function(data){
               eval(success+'('+JSON.parse($.trim(data))+')');
     }
     ,error: function (xhr, ajaxOptions, thrownError){
               eval(success+'('+data+')');
     }
     });
}

I mamy już wszystko. CakePHP + AJAX w 3 minuty :)

:, , , , , ,

Leave a Reply

Kalendarz

January 2012
M T W T F S S
« Oct    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
Linki sponsorowane:
sławomir siudek * inmarsat satellite inmarsat Phones inmarsat satellite phones * niszczenie danych * pozycjonowanie * Tworzenie stron Szczecin * Strony internetowe szczecin * franczyza alkohole