Łatwiej jest to zrozumieć, jeśli podzielisz kod na dwie części.
Pierwsza część $("#reviews").append("<%= ... %>");
to javascript z erb. Oznacza to, że <%= ... %>
zostanie zastąpiony przez kod ruby w środku, który zwróci. Wynik tej zamiany musi być prawidłowym skryptem javascript, w przeciwnym razie zgłosi błąd, gdy klient spróbuje go przetworzyć. To pierwsza rzecz: potrzebujesz prawidłowego javascript .
Inną rzeczą, którą należy wziąć pod uwagę, jest to, że wszystko, co generuje ruby, musi być zawarte w łańcuchu javascript z podwójnymi cudzysłowami - zwróć uwagę na podwójne cudzysłowy wokół <%= ... %>
. Oznacza to, że wygenerowany javascript będzie wyglądał następująco:
$("#reviews").append("...");
Teraz przyjrzyjmy się rubinowej części wewnątrz pliku <%= ... %>
. Co robi render(:partial => @review)
? To renderowanie częściowe - co oznacza, że może renderować dowolny rodzaj kodu - html, css ... lub nawet więcej javascript!
Więc co się stanie, jeśli nasz podrzędny fragment zawiera prosty kod HTML, taki jak ten?
<a href="/mycontroller/myaction">Action!</a>
Pamiętasz, że Twój javascript przyjmował jako parametr ciąg znaków w podwójnych cudzysłowach? Jeśli po prostu zastąpimy go <%= ... %>
kodem tej części, to mamy problem - zaraz po tym href=
jest podwójny cudzysłów! JavaScript nie będzie prawidłowy:
// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");
Aby tak się nie stało, chcesz uniknąć tych znaków specjalnych, aby łańcuch nie został przecięty - potrzebujesz czegoś, co zamiast tego wygeneruje:
<a href=\"/mycontroller/myaction\">Action!</a>
To co escape_javascript
robi. Zapewnia, że zwracany ciąg nie „zepsuje” javascript. Jeśli go użyjesz, uzyskasz pożądane wyjście:
$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")
Pozdrowienia!