AJAX mi nie bangla w template'ach RJS

No sam już nie wiem. Zacząłem się wreszcie uczyć AJAX-a, przeczytałem (ze zrozumieniem…) rozdział 9 z “Agile…” i podany tam przykład przeflancowałem do swojej aplikacji, praktycznie bez zmian strukturalnych. No i nie działa. Sprawdziłem, że z Railsem i przeglądarką jest wszystko w porządku, bo sam przykład z książki odpalony działa (czyli aplikacja Depot działa z AJAX-em). Natomiast kod przeniesiony do mojego programu wykonuje się (wstawiałem wszędzie raise żeby sprawdzić czy kod się wykonuje), ale przeglądarka nic nie wyświetla.
Po sprawdzeniu wszystkiego przypadkiem doszedłem do tego, że jak kod ajaxowy wpisany jest w template RJS, to mi nie działa, natomiast wpisany bezpośrednio do kontrolera:

render :update do |page| page.replace_html("new_rate", :partial => "new_rate", :object => @rate) page[:new_rate].visual_effect :blind_down, :duration => 0.2 page[:new_rate].visual_effect :highlight, :startcolor => "#FF9200", :endcolor => "#FFFFFF", :duration => 0.5 end
nagle zaczyna działać! Nie wiem zupełnie dlaczego, swoją aplikację rozebrałem już na kawałki i sprawdziłem wszystko, od treści layoutu począwszy i deklaracji DOCTYPE, poprzez kontroler, wywołania partiali, nazwy zmiennych globalnych, lokalnych i tych wynikających z wywoływania partiali. Wszystko w najlepszym porządeczku, tylko że RJS nie daje rezultatu. Template’u RHTML o takiej samej nazwie jak akcja i plik RJS nie ma, przywileje do pliku RJS w porządku. I jeszcze raz powtarzam, że kod z pliku RJS na pewno się wykonuje, bo jak wstawię tam raise “dupa” to widzę w konsoli to piękne słowo.

Czy ktoś spotkał się z podobnym problemem, żeby kod render :update do … w kontrolerze działał, a to samo przeniesione do template’u RJS nie powodowało żadnych zmian w przeglądarce, choć kod w pliku RJS na sto procent się wykonuje?

Debugujesz jakos?

  1. Czy masz moze ustawiony debug dla RJS ?
    config.action_view.debug_rjs = true

Jesli tak to czy cos wyrzuca w okienko?

  1. Korzystasz moze z FF ?
    Zainstaluj sobie Firebug i sprawdz czy aplikacja wysyla cos do przegladarki.

Raz mialem taki problem z 1.1.6 ale po upgradzie js’ow zaczelo dzialac.

Drugi raz bylo cos nie tak z cacheowaniem i chyba jeszcz cos bylo, poszukam.

Tak, mam włączone config.action_view.debug_rjs = true, ale nic nie krzyczy.

Tak, mam Firebuga od przed chwilą (piękna rzecz!), aplikacja zwraca coś, co wygląda mi prawidłowo:

try { Element.show("new_rate"); Element.update("new_rate", "<div>\n\tnew_rate.inspect: #<PersonTaskRate:0x3459324 @person_id=1>, @new_rate_hidden .... } catch (e) ....
niestety w DOM inspektorze nadal mam smutny ukryty DIV

…. Już się zastanawiałem, czy Element.show rzeczywiście likwiduje przypisanie stylu display: none;, ale ten sam kod wpisany do kontrolera przecież działa.

Co do cache’owania, to działam w środowisku development gdzie cache’owanie jest przecież wyłączone. Moja aplikacja zresztą sama z siebie nic jeszcze nie cache’uje, nie ten etap (mojego rozwoju).

A nie masz przypadkiem w widokach rhtmla o takiej samej nazwie jak rjs?

Jeżeli nie, to możesz się spróbować pobawić respond_to. Może to wymusi załadowanie tego rjs’a.

Pozdrawiam

[quote=komor]Tak, mam włączone config.action_view.debug_rjs = true, ale nic nie krzyczy.

Tak, mam Firebuga od przed chwilą (piękna rzecz!), aplikacja zwraca coś, co wygląda mi prawidłowo:

try { Element.show("new_rate"); Element.update("new_rate", "<div>\n\tnew_rate.inspect: #<PersonTaskRate:0x3459324 @person_id=1>, @new_rate_hidden .... } catch (e) ....
[/quote]
Element.show dobrze zadziala i zmieni atrybut display z none na block

new_rate.inspect rozumiem ze chcesz aby inspect zwrocil ci wszystko na stronie.
kiedys spedzilem 3h z .inspect i nic a nic nie widzialem na stronie, albo tylko sam #. okazalo sie ze inspect to co zwracal dla przegladarki to wygladalo jak cos otoczone “jakimis” tagami. tak wiec po 3h wcisnalem ctrl+u i zrodlo strony wyjawilo mi swoja prawde. to tak a’propos kosmosu ale jednego dnia moze pomoc.
i zaczalem tylko uzywac ‘debug costam’.

a konkretnie, to wyglada ze FireBug ‘lapie’ to co wyrzuca aplikacja i wyglada na poprawnie, przygladnij sie tez zakladce ‘Headers’ tak dla pewnosci czy jest wszystko to co ma wskazywac ze response jest zwiazany z ajaxem.

Jesli tak to pozostaje, cos z cacheowaniem przegladarki, albo problem z js’ami (jesli tak to rake rails:update:javascripts ).

Proponuje sprawdzic w innej przegladarce, ewentualnie, rake tmp:cache:clear.

Hmm, dalej nie moge sobie przypomniec na 100% jak ten problem rozwiazalem kiedy uzywalem R1.1.5 lub R1.1.6

[quote=drogus]A nie masz przypadkiem w widokach rhtmla o takiej samej nazwie jak rjs?

Jeżeli nie, to możesz się spróbować pobawić respond_to. Może to wymusi załadowanie tego rjs’a.

Pozdrawiam[/quote]
tez sie kiedy na to zlapalem przy tej samej nazwie. oczywiscie respond_to wtedy pomoglo :slight_smile:

Wyglada na to, ze aplikacja zwraca poprawnie RJS’a.
Jak widac FireBug sie swietnie nadaje (cudowna rzecz).

Nie mam, krótki troubleshooting opisany w książce przeczytałem i sprawdziłem.

Spróbuję, choć na razie bezpośrednie użycie render :update do |page| … akurat w moim przypadku sprawdza się dobrze i wygląda czytelnie. Pozostaje pytanie, dlaczego nie działa to, co powinno działać…

Mozesz sprawdzic czy to zadziala jak wstawisz w .rjs ?

page.alert(“DZIALA RJS !”)

Nie wszystko, ten inspect wstawiłem po to, żeby widzieć, czy w ogóle kod z kontrolera się wykonuje, new_rate to model, którego pusta instancja jest zakładana w tej akcji kontrolera, która jest wyzwalana przez ajaksowe żądanie.

[quote=tczubinski]FireBug ‘lapie’ to co wyrzuca aplikacja i wyglada na poprawnie, przygladnij sie tez zakladce ‘Headers’ tak dla pewnosci czy jest wszystko to co ma wskazywac ze response jest zwiazany z ajaxem.

Jesli tak to pozostaje, cos z cacheowaniem przegladarki, albo problem z js’ami (jesli tak to rake rails:update:javascripts ).

Proponuje sprawdzic w innej przegladarce, ewentualnie, rake tmp:cache:clear.[/quote]
Headers wyglądają poprawnie, o ile potrafię to ocenić. Porównywałem z działającym kodem remote_function z innego kontrolera. Przy korzystaniu z remote_function nie mam problemu, choć oczywiście różnica jest taka, że zwracany wynik to nie kod JS tylko kawałek HTML.

Na wszelki wypadek wykonałem też polecane przez Ciebie rake rails:update:javascripts, a wielokrotnie wcześniej rake tmp:clear. Nic nie daje :slight_smile:

Jeśli chodzi o inne przeglądarki to sprawdziłem Firefox, Camino, Safari, Opera 9, do Explodera nie mam dostępu - wszędzie to samo, czyli coś musi być w moim kodzie (lub w Railsach, hehe…).

Na razie odpuszczam sobie i zajmę się czymś innym, może potem mnie oświeci co się stało.

[quote=tczubinski]Mozesz sprawdzic czy to zadziala jak wstawisz w .rjs ?

page.alert(“DZIALA RJS !”)[/quote]
Nie działa. Owszem, Firebug pokazuje, że pojawiło się to zwracanym kodzie JS:

try { Element.show("new_rate"); Element.update("new_rate", "<div>\n\tnew_rate.inspect: #<PersonTaskRate:0x357abcc @person_id=1>, @new_rate_hidden.inspect: false\n</div>"); $("new_rate").visualEffect("blind_down"); $("new_rate").visualEffect("highlight", {startcolor: "#88ff88", endcolor: "#114411"}); alert("DZIALA RJS !"); } catch (e) { alert('RJS error:\n\n' ...
Może jeszcze na wszelki wypadek podam jak wyglądają Headers:

Host localhost:3000 User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X; pl; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2 Accept text/javascript, text/html, application/xml, text/xml, */* Accept-Language pl,en;q=0.5 Accept-Encoding gzip,deflate Accept-Charset ISO-8859-2,utf-8;q=0.7,*;q=0.7 Keep-Alive 300 Connection keep-alive X-Requested-With XMLHttpRequest X-Prototype-Version 1.5.0 Content-Type application/x-www-form-urlencoded; charset=UTF-8 Referer http://localhost:3000/admin/person/show/1 Content-Length 26 Cookie _pro_forma_id=4d542fdb0b84ad89b23534d5e45cfe60; _session_id=7ab0e66e0a9fb3906b4480e40ac6953a Pragma no-cache Cache-Control no-cache

komor, przyznam, jestem nieco zdziwiony, ze wyglada wszystko ok a rjs ci nie dzialaja na dodatek firebug pokazuje, ze responsy i requesty sa ok.

wydawalo mi sie, ze railsy uzywaja tych samych metod renderowania js’ow dla kontrolerow tak jak i dla rjs’ow.
a tu prosze wyglada, ze moze byc jakas roznica. problem jest intrygujacy, jestem ciekawy czy masz ten sam response dla ajaxa wykonywanego z kontrolera i z rjs’a.

tez wyglada jakby RJS zwracal ci z naglowkiem ‘Content-Type: text/html’ zamiast ‘Content-Type: text/javascript’

z zasady analizuje wszystko bardzo dokladnie, jestem uparty :wink:

[quote=tczubinski]wydawalo mi sie, ze railsy uzywaja tych samych metod renderowania js’ow dla kontrolerow tak jak i dla rjs’ow.
a tu prosze wyglada, ze moze byc jakas roznica. problem jest intrygujacy, jestem ciekawy czy masz ten sam response dla ajaxa wykonywanego z kontrolera i z rjs’a.[/quote]
Coś musi siedzieć w mojej aplikacji, skoro na tym samym zestawie komponentów przykładowa aplikacja Depot z książki - działa prawidłowo.

Kiedyś w mojej aplikacji ustawiałem globalnie nagłówki na UTF-8:

[code] before_filter :set_default_content_type, :authorize

def set_content_type(content_type)
@response.headers[“Content-Type”] = content_type
end

def set_default_content_type
  set_content_type("text/html; charset=utf-8")
end[/code]

oraz ustawiałem $KCODE = ‘u’, require ‘jcode’ ale w Rails 1.2.x już tego nie trzeba robić i wywaliłem to z aplikacji. Więc na pewno Content-Type nie jest przeze mnie psuty.

No ja też będę na to uparty :slight_smile: ale w wolnej chwili, jak inne sprawy oblecę.

Mam tę pluskwę cholerną! :slight_smile: Wreszcie. Przeszukałem projekt w poszukiwaniu $KCODE oraz Content-Type i okazało się, że używany przeze mnie plugin LocalizationSimplified (http://rubyforge.org/projects/l10n-simplified/) w swoim kodzie inicjującym przestawia Content-Type:

[code]$KCODE = ‘u’

Response header necessary with some lang-files (like lang_pirate.rb for some reason)

response.headers[“Content-Type”] = “text/html; charset=utf-8”[/code]
Po usunięciu tych wpisów wszystko zaczęło automagicznie działać. Sprawdziłem, że aktualny release pluginu jest już uaktualniony do Rails 1.2.x, czyli nie grzebie już ani w $KCODE ani w Response-Headers, jako że Rails domyślnie ustawione jest na UTF-8.

Dzięki za naprowadzenie na trop!

:slight_smile:

Mysle, ze poleganie na Firebug w wiekszosci przypadkow zaoszczedzi czasu i nerwow.
Odpowiedz tez czekala w zakladce Firebug’a tj. Response i Request Headera.

Pozdrawiam

Właśnie grzebałem się z podobnym problemem… inny powód takiego błędu:

w pliku .rhtml

<%= observe_field( 'id_elementu_wywolujacego_akcje', :update => 'id_elementu_html_ktory_zmieniamy', :url => { :action => :akcja_kontrolera_ktora_wywolujemy}, #=nazwie pliku .rjs :on => 'changed') %>
w pliku .rjs

    page.replace_html 'id_elementu_html_ktory_zmieniamy', 'boo'

powód - wykonuje się podwójny update lub coś w podobie - wypisuje się javascript w stylu
try{ … } catch(e) …
zamiast naszego oczekiwanego tekstu.

Wywalamy “:update…” z tagu observe_field i działa jak należy