Marek Bożych

Marek Bożych Programista
Javascript/Ruby on
Rails

Temat: zapytanie 'delete' ajax/jQuery

Witam,
Mam pewne niejasnosci co do zapytan ajaxowych w cakephp, dla przykladu podam prosta funkcje ktora usuwa rekord z bazy:

kontroler: http://pastebin.com/8RXH9xYR
ajax: http://pastebin.com/KDLAxXmj

przewertowalem juz naprawde sporo i nie moge dojsc jak zrobic zeby nie przeladowywac calej strony, czyli window.location.replace() tylko samego div'a gdzie sa wyswietlane dane z tabeli, kombinowalem z .load() /jQuery/ ale takze bez skutku
Konrad Kluźniak

Konrad Kluźniak Webdeveloper /
Designer

Temat: zapytanie 'delete' ajax/jQuery

Po pierwsze zrobiłbym sobie ajaxowy kontroller tylko do ajaxa:

// Controller/AjaxController.php
class AjaxController extends AppController {

public $name = 'Ajax';
public $layout = 'ajax';

public function beforeFilter() {
if ($this->request->is('get')) {
throw new NotFoundException;
};
$this->autoRender = false;
}

// Przykładowa metoda:
public function saveAlt() {
$this->layout = 'ajax';
$this->loadModel('Photo');
$this->Photo->id = ($this->request->data['id']);
$this->Photo->saveField('alt', $this->request->data['alt']);
}
}

Po drugie, wzywam akcje w skrypcie ajax tak:
// w widoku
$.ajax({
url: '<?php echo $this->Html->url(array('controller'=>'ajax', 'action'=>'saveAlt'));?>'

Po trzecie, to: $('#submit_delc').click(function(){
zamieniłbym na ('#submit_delc').on('click, function() {

Po czwarte zamiast tego:
window.location.replace('/cakephp/customers/index');

zrobiłbym sobie diva np: #dynamicContent , w którym ładowałbym właśnie funkcją .$load() zmieniane dane, po kliknięciu w #submit_delc czyli tej akcji:
('#submit_delc').on('click, function() - załaduj loadem content w użyciu ajaxa.

mam nadzieję że pomoże.
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: zapytanie 'delete' ajax/jQuery

Nie będzie copy/paste ale:
1. żadne tam ustawianie ręczne layoutów, czy robienie oddzielnego kontrolera dla requestów ajaxowych!
2. żeby nie renderowało layoutu wystarczy dołączyć komponent RequestHandler
3. jeśli potrzebujesz w akcji robić coś tylko jeśli jest to request ajaxowy, to dajesz
if($this->request->is('ajax')

4. nie do końca rozumie co chcesz osiągnąć, ale problem jest chyba w niezrozumieniu samego ajax/posługiwania się nim. poszukaj przykładów, są tego naprawdę miliony. nawet tutaj http://api.jquery.com/jQuery.post/ jest przykład załadowania tego co ci zwraca request.
5. nie wiem co chcesz zwracać, ale ja tam jestem przeciwnikiem odsyłania htmla. masz do tego jsona. wyślij jsona i zbuduj na jego bazie htmla już po stronie przeglądarki.
6. ajax ma być czymś co przyspiesza działanie, nie ma więc sensu czekać na zakończenie wszystkiego przez cake. w akcji, po zrobieniu tego co potrzebujesz dajesz exit i tyle. jeśli zwracasz dane jsonem to
echo json_encode($data); exit;
albo samo
return new CakeResponse(array('body' => json_encode($data)));
Konrad Kluźniak

Konrad Kluźniak Webdeveloper /
Designer

Temat: zapytanie 'delete' ajax/jQuery

Starałem sie dać raczej konkretniejszą poszlakę, koledze otwierającemu temat, ty raczej napisałeś bardzo suche info , w stylu " ja tam jestem przeciwnikiem".

Jeśli uważasz że masz recepte, przeanalizuj kod is spróbuj mu pomóc doraźnie, tak żebyś przeciwnikiem nie był.

Samo if($this->request->is('ajax') sprawy raczej nie załatwi, kontrolerowi trzeba i tak wytłumazyć że ma do czynienia z ajaxem, więc za każdym razem się powtarzasz.

Zrobienie kontrolera dla ajaxa nie jest wg mnie złym pomysłem.

ajax ma być czymś co przyspiesza działanie - raczej wygodę użytkowania

nie ma więc sensu czekać na zakończenie wszystkiego przez cake - na coś trzeba jednak poczekać, choćby to, na co skała się nazwa AJAX

dajesz exit i tyle - czasem trzeba jakąś operację powtórzyć, a ja wtedy nie chcę " wychodzić " :)

Innymi słowy: masz coś konkretnego do zaproponowania koledze czy nie ?
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: zapytanie 'delete' ajax/jQuery

Ech... post jest na temat problemów z ajaxem/jquery/cakephp. Informacje, które podałem naprowadzają na to jak trzeba z ajaxem postępować w cakephp (requesthandler, is('ajax')) i jak poradzić sobie z aktualizacją diva (przykłady w dokumentacji od $.post). Jest tutaj wszystko czego potrzeba, że rozwiązać problem i jednocześnie poprawnie napisać kod.

"przyspiesza działanie" = "użytkownikowi działa szybciej".

"Samo if($this->request->is('ajax') sprawy raczej nie załatwi, kontrolerowi trzeba i tak wytłumazyć że ma do czynienia z ajaxem, więc za każdym razem się powtarzasz. " - jeśli mówimy o layoucie to od tego jest requesthandler (o czym wspomniałem), jeśli o logice (chce robić tylko coś jeśli to ajax), to tak, wystarczy.

"na coś trzeba jednak poczekać, choćby to, na co skała się nazwa AJAX" "czasem trzeba jakąś operację powtórzyć, a ja wtedy nie chcę " wychodzić " :)" - no naprawdę chcesz podyskutować na takim poziomie? :)

Mam wklejać kod? Nie no plz... Naprawdę napisałem wszystko co potrzeba w tym temacie. Wystarczy wejść w dokumentację i przeczytać (to ma być początek rozwiązywania problemów, a nie zadawanie pytań i czekanie na gotowy kod).
Nie wiedział? Ok, każdy może nie wiedzieć. Podałem więc tematy, z którymi powinien się bliżej zapoznać. Na tym polega programowanie, a nie na ślepym copy/paste.
Spróbuje rozwiązać problem, pójdzie krok dalej, ale się nie uda i wróci z kolejnymi pytaniami. I dobrze.

Zgadza się, podałeś "gotowe" rozwiązanie, ale to co zaproponowałeś jest złą praktyką.
Konrad Kluźniak

Konrad Kluźniak Webdeveloper /
Designer

Temat: zapytanie 'delete' ajax/jQuery

Dobrze wiesz, że ta odpowiedź problemu kolegi nie rozwiąże, nawiasem mówiąc, my dyskutujemy a interesanta nie ma:)
Bartek Naski

Bartek Naski CakePHP developer

Temat: zapytanie 'delete' ajax/jQuery

mom, mi też do głowy nie przyszło używać odrębnego controllera do ajaxów, czasem tylko jak mam dużo roboty z uploadem obrazków to stawiam osobny kontroller, i to tez jak robię na BLOB, a tak to trochę szkoda miejsca...

ale rozumiem pytającego jak sobie przypomnę swoje schody np. z JsHelperem.

Marek odświeża ci stronę bo nie załadowałeś do widoku writebufera:

<?php echo $this->Js->writeBuffer(); ?>

nawet bez ->is ajax ci wykona tą akcję, ale prawidłowe działanie wskazał Kamil
ponieważ jeżeli nie użyjesz is ajax to każdy będzie ci kasował rekordy nawet boty
Bartek Naski

Bartek Naski CakePHP developer

Temat: zapytanie 'delete' ajax/jQuery

używacie całego tego zestawu do ajax? :
$this->layout = 'ajax';
$this->autoLayout = false;
$this->autoRender = false;
bo ja tylko:
$this->autoRender = false;
i to w takiej postaci:
if ($this->request->is('ajax')) {
$this->autoRender = false;
....
}
Marek Bożych

Marek Bożych Programista
Javascript/Ruby on
Rails

Temat: zapytanie 'delete' ajax/jQuery

Interesant byl w terenie i wlasnie czyta wasze posty, @Kamil:
Ad 2. "żeby nie renderowało layoutu wystarczy dołączyć komponent RequestHandler"
- mam dodane public $components = array('RequestHandler', 'Paginator');

Ad 3. "jeśli potrzebujesz w akcji robić coś tylko jeśli jest to request ajaxowy, to dajesz..."
- ok, dodane

Ad 4. "nie do końca rozumie co chcesz osiągnąć..."
- chce osiagnac to, ze tresc na stronie bedzie sie aktualizowala dynamicznie, czyli user usuwa cos z bazy, wykonywane jest ponowne zapytanie do bazy zeby wylistowac np wszystkie zamowienia, i tak za kazdym razem po usunieciu jakiegos rekordu z bazy, czyli aby usunac cos wykonywana jest funkcja 'deleteSelected' i zeby ponownie wylistowac rekordy funkcja 'index' -> http://pastebin.com/MUSiHgp8, z tego co zrozumialem, 'on success' (w ajaxie) musi zostac wykonana funkcja 'index' (z kontrolera cake) i wynik zwrocony np w divie 'result'. Wydaje mi sie, ze mam zle przygotowana funkcje index ktora nie jest dostosowana pod zapytanie ajaxowe, z ajaxem mam stycznosc od niedawna dlatego sa pewne braki w fundamentalnej wiedzy, ale doczytam dokumentacje ktora podeslal Kamil
Bartek Naski

Bartek Naski CakePHP developer

Temat: zapytanie 'delete' ajax/jQuery

hmm... będzie ciężko :)
Marek Bożych

Marek Bożych Programista
Javascript/Ruby on
Rails

Temat: zapytanie 'delete' ajax/jQuery

Wlasnie to zauwazylem, chcialem zrobic prosta funkcje w ajaxie ale wychodzi na to ze wiekszosc funkcji bede musial przebudowac pod ajaxa bo jedno laczy sie z drugim, i powstaje efekt domina.
Bartek Naski

Bartek Naski CakePHP developer

Temat: zapytanie 'delete' ajax/jQuery

no nie o to chodziło, w cakephp ajax jest prosty, tak prosty że nic o nim nie znajdziesz za wiele w google. dlatego jest tak trudny :) wejdź na stronę cakephp.org i poczytaj rozdział o JsHelperze. Ja na swojej stronce rozpisuję się dla początkujących ale do ajaxa to jeszcze nie doszedłem, mam dopiero troszkę z HtmlHelpera.
Mimo-wszystko możesz zaglądnąć może ci się coś przyda...
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: zapytanie 'delete' ajax/jQuery

Ważne na początek to wiedzieć, czy z panelu będzie korzystała jedna osoba na raz, czy więcej?

1. jeśli jedna:
proponuję olać zwracania ponownej listy rekordów a jedynie usunąć te rekordy, które zostały zaznaczone do usunięcia. efekt ten sam, a nic nie musisz odsyłać z serwera (no chyba, że chcesz na wypadek odesłać idki wszystkich usuniętych rekordów).

2. jeśli więcej osób:
faktycznie musisz wylistować ponownie rekordy. ale teraz:
a) najłatwiej, ale mniej ładnie będzie zwrócić html, więc wystarczy ci ta akcja co masz, ale faktycznie możesz potrzebować inny widok dla odpowiedzi ajaxowej.
i znowu masz kilka opcji:
- oddzielny plik dla tego widoku np. index_ajax.ctp i w akcji dajesz $this->render('index_ajax');
- pobawić się różnymi fajnymi rzeczami w cake jak http://book.cakephp.org/2.0/en/views.html#extending-views http://book.cakephp.org/2.0/en/views.html#view-blocks
- przypisywać jakaś zmienną do widoku jeśli to ajax i dawać ify w twoim index.ctp, tak żeby odsyłać to co potrzebujesz
b) odesłać jsona z danymi, a listing zbudować za pomocą jsa. i tutaj masz kilka opcji:\
- http://book.cakephp.org/2.0/en/views/json-and-xml-view...
- echo json_encode($data); exit;
- return new CakeResponse(array('body' => json_encode($data)));

a odnośnie jsa w cakephp, to jakoś on do mnie nie przemawia. masz niby helper, ale mam wrażenie, że z tym jest jak z bake, którego jak sami przyznają, część rozwijających cake w ogóle nie używa. dla mnie js to inna bajka i powinien być przeniesiony całkowicie do plików js, a nie wrapowany phpowymi funkcjami.

z samą podmianą zawartości diva raczej sobie poradzisz ;)
Bartek Naski

Bartek Naski CakePHP developer

Temat: zapytanie 'delete' ajax/jQuery

nom. Kolega ma rację... ale JsHelper jest bardzo przyjazny i fajnie można się oprzeć na nim na niewielkich projektach, jego minusem jest to że jest lekko "ograniczony" zwłaszcza w zakresie jQuery, ale nie rezygnowałbym z nauki. Można w nim szybko ogarniać i listy i formularze i proste linki po ajax, teraz nie mam czasu ale w przyszłości wrzucę parę przykładów do mojego repo na stronkę http://cakephp.com.pl
Marek Bożych

Marek Bożych Programista
Javascript/Ruby on
Rails

Temat: zapytanie 'delete' ajax/jQuery

@Bartek: JShelper jakos do mnie nie przemawia, moze dla kogos kto np programuje kilka lat w ajaxie i ma w miare biegla znajomosc jest to przydatne narzedzie, ale ja osobiscie wole odseparowac javascripty od 'automagicznych' helperow cakephp :)

@Kamil: Na chwile obecna bedzie korzystac jedna osoba, ale w przyszlosci moze byc ich kilka wiec wole zeby aplikacja byla skalowalna 'w razie w', dzieki za pomysly jak to zrobic, mam nadzieje ze najblizszym czasie to ogarne.

To 'odswiezanie div'ow' nie jest tak strasznie wazne dla mnie, ale zastanawialem sie co bedzie bardziej wydajne dla serwera i bazy danych w przypadku gdy w tym samym czasie np 100 uzytkownikow bedzie pracowalo jednoczesnie, mowie o sytuacji gdzie dla kazdego uzytkownika jest oddzielna baza danych w obrebie tego samego serwera, czy 100x zapytanie window.reload() czy 100x zapytanie ajaxowe ktore zwroci tylko elementy danej tabeli.



Wyślij zaproszenie do