Använda Diskreta JavaScript och AJAX med Rails 3

Som jag nämnde i min tidigare Ruby on Rails-handledning är Unobtrusive JavaScript (UJS) en av de coolaste nya funktionerna i Rails 3. UJS tillåter Rails-genererad kod att vara mycket renare, hjälper till att skilja din JavaScript-logik från dina HTML-layouter och urkopplar Rails från Prototype JavaScript-biblioteket. I denna handledning kommer vi att titta på dessa funktioner och lära dig hur du använder dem i en enkel Rails 3-applikation.


Bakgrund: Vad är diskreta JavaScript?

För att börja, vad exakt är UJS? Enkelt, UJS är JavaScript som är skilt från din HTML-markup. Det enklaste sättet att beskriva UJS är med ett exempel. Ta en onclick event handler; vi kunde lägga till det påträngande:

 Länk

Eller vi kan lägga till det på diskret sätt genom att fästa händelsen till länken (med jQuery i det här exemplet):

 Länk 

Som nämnts i min introduktion har den andra metoden en rad fördelar, inklusive enklare felsökning och renare kod.

"Rails 3, å andra sidan, är JavaScript-ramar agnostic. Med andra ord kan du använda din JavaScript-ramverk, förutsatt att ett Rails UJS-genomförande existerar för den ramen."

Fram till version 3 genererade Ruby on Rails obtrusive JavaScript. Den resulterande koden var inte ren, men ännu värre, den var tätt kopplad till prototypens JavaScript-ramverk. Detta innebar att om du inte skapade ett plugin eller hackade Rails, var du tvungen att använda Prototype-biblioteket med Rails JavaScript-hjälpar metoder.

Rails 3, å andra sidan, är JavaScript-ramar agnostic. Med andra ord kan du använda din JavaScript-ramverk, förutsatt att ett Rails UJS-genomförande existerar för den ramen. De nuvarande UJS-implementeringarna omfattar följande:

  • Prototyp (standard)
  • jQuery
  • MooTools

Rails 3 implementerar nu alla dess JavaScript Helper-funktionalitet (AJAX skickar, bekräftelseanmälningar etc.) diskret genom att lägga till följande HTML 5 anpassade attribut till HTML-element.

  • data-metod - REST-metoden att använda i formulärinsändningar.
  • data-bekräfta - bekräftelsemeddelandet att använda innan du utför någon åtgärd.
  • data-fjärrkontroll - om det är sant, skicka via AJAX.
  • data-disable-with - inaktiverar formulärelement under formulärinsändning

Till exempel, denna länk tagg

 Förstöra

skulle skicka en AJAX-bortförfrågan efter att ha frågat användaren "Är du säker?".

Du kan tänka dig hur mycket svårare att läsa som skulle vara om allt det JavaScript var inline.

Nu när vi har granskat UJS och hur Rails implementerar UJS, låt oss skapa ett projekt och titta på några specifika applikationer. Vi använder jQuery-biblioteket och UJS-implementeringen i den här handledningen.


Steg 1: Ställa in projektet

Eftersom vi skapar ett nytt projekt från början, är det första vi behöver göra att skapa projektet genom att skriva följande:

 skenar ny blogg - skip-prototyp

Lägg märke till att jag instruerar Rails att hoppa över prototypens JavaScript-fil, eftersom jag ska använda jQuery-biblioteket.

Låt oss starta servern bara för att se till att allt verkar fungera.

Och voila!

Nu när vi har satt upp vårt projekt måste vi lägga till jQuery och jQuery UJS till vårt projekt. Du är fri att organisera din JavaScript men du vill, men Rails konventionen för att strukturera dina JavaScript-filer är som följer (alla dessa filer går i offentliga / javascripts):

  • ram JavaScript-fil (jquery.js, prototype.js eller mootools.js)
  • rails.js - koden för implementering av skenor UJS (för vilken ram du har valt)
  • application.js - din applikation JavaScript

Om du inte redan har laddat ner jquery.js (eller hänvisa till en CDN) och rails.js och inkludera dem i din offentliga / javascripts katalog.

Det sista vi behöver göra för att komma igång är att faktiskt berätta att Rails ska inkludera dessa js-filer på var och en av våra sidor. För att göra detta, öppna application.rb i din config-katalog och lägg till följande rad

 config.action_view.JavaScript_expansions [: defaults] =% w (jquery rails application)

Denna konfigurationsobjekt berättar att Rails ska inkludera de tre ovan nämnda JavaScript-filerna.

Alternativt kan du ta tag i jQuery från en CDN (dvs http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js) genom att manuellt inkludera en skriptmärke som pekar på rätt plats. Om du gör det, måste du ta bort "jquery" från konfigurationsobjektet JavaScript_expansions.


Steg 2: Generera viss kod

För att visa skenorna UJS-funktionalitet måste vi först ha en kod att arbeta med. För den här demo kommer vi bara att ha ett enkelt Post-objekt. Låt oss skapa det nu

 skenor generera ställning Postnamn: strängtitel: stränghalt: text

Och sedan låt oss migrera vår databas för att skapa inläggstabellen.

 rake db: migrera

Okej, vi är bra att gå! Om vi ​​navigerar till http: // localhost: 3000 / inlägg / new, vi borde se ett formulär för att skapa en ny inlägg.

Ok, det fungerar allt! Låt oss nu gräva och se hur du använder UJS- och AJAX-funktionaliteten bakad i Rails.


Steg 3: Lägga till AJAX

Nu när alla nödvändiga JavaScript-filer ingår, kan vi faktiskt börja använda Rails 3 för att implementera en del AJAX-funktionalitet. Även om du kan skriva alla anpassade JavaScript som du vill, ger Rails några bra inbyggda metoder som du kan använda för att enkelt utföra AJAX-samtal och andra JavaScript-åtgärder.

Låt oss titta på några vanliga railshjälpare och JavaScript som de genererar

AJAX-formulärinsändning och Javascript-ERB-filer

Om vi ​​tittar på vår inläggsformulär kan vi se att när vi skapar eller redigerar ett inlägg, skickas formuläret manuellt och vi vidarebefordras till en skrivskyddad vy av den posten. Vad händer om vi ville skicka in formuläret via AJAX istället för att använda en manuell inlämning?

Rails 3 gör det enkelt att konvertera någon form till AJAX. Öppna först din _form.html.erb dela i app / visningar / inlägg och ändra första raden från:

 <%= form_for(@post) do |f| %>

till

 <%= form_for(@post, :remote => sant) gör | f | %>

Före Rails 3, lägger du till : remote => true skulle ha genererat en massa inline-JavaScript i formtaggen, men med Rails 3 UJS är den enda ändringen tillägget av ett HTML 5-anpassat attribut. Kan du upptäcka det?

 

Attributet är uppgifter-remote = "true", och Rails UJS JavaScript binder till alla former med det attributet och skickar dem via AJAX istället för en traditionell POST.

Det är allt som behövs för att AJAX ska skicka in, men hur utför vi en återuppringning efter att AJAX-samtalet återvänder?

Det vanligaste sättet att hantera avkastning från ett AJAX-samtal är genom att använda JavaScript ERB-filer. Dessa fungerar precis som dina vanliga ERB-filer, men innehåller JavaScript-kod istället för HTML. Låt oss prova det.

Det första vi behöver göra är att berätta för vår controller hur man svarar på AJAX-förfrågningar. I posts_controller.rb (app / controllers) kan vi berätta för vår controller att svara på en AJAX-begäran genom att lägga till

 format.js

i varje svara för att blockera att vi ska ringa via AJAX. Till exempel kan vi uppdatera skapningsåtgärden så att den ser ut så här:

 def skapa @post = Post.new (params [: post]) reply_to | format | om @ post.save format.html redirect_to (@post,: notice => 'Post skapad.') format.js else format.html render: action => "new" format.js slutet änden

Eftersom vi inte angav några alternativ i answer_to-blocket, svarar Rails på JavaScript-förfrågningar genom att ladda en .js ERB med samma namn som controller-åtgärden (create.js.erb, i det här fallet).

Nu när vår controller vet hur man hanterar AJAX-samtal måste vi skapa våra åsikter. För det nuvarande exemplet, lägg till create.js.erb i din app / visningar / inlägg katalogen. Den här filen kommer att bli gjord och JavaScript inuti kommer att utföras när samtalet avslutas. För nu ska vi helt enkelt skriva över formuläret med titeln och innehållet i blogginlägget:

 $ ( 'Kropp'). Html ("

<%= escape_javaScript(@post.title) %>

").bifoga("<%= escape_javaScript(@post.content) %>");

Nu om vi skapar en ny post får vi följande på skärmen. Framgång!

Fördelen med den här metoden är att du kan interspiera rubinkod som du har ställt in i din kontroller med JavaScript, vilket gör det väldigt enkelt att manipulera din vy med resultatet av en förfrågan.

AJAX-återuppringningar med anpassade JavaScript-händelser

Varje Rails UJS-implementering ger också ett annat sätt att lägga till callbacks till våra AJAX-samtal - anpassade JavaScript-händelser. Låt oss titta på ett annat exempel. På vår index-indexvy (http: // localhost: 3000 / inlägg /) kan vi se att varje inlägg kan raderas via en länk för borttagning.

Låt oss AJAXify vår länk genom att lägga till: remote => sant och dessutom ge den en CSS-klass så att vi enkelt kan hitta denna POST med en CSS-väljare.

 <%= link_to 'Destroy', post, :confirm => 'Är du säker?',: Method =>: delete,: remote => true,: class => 'delete_post'%>

Vilket ger följande utmatning:

 Förstöra

Varje rails UJS AJAX-samtal ger sex anpassade händelser som kan kopplas till:

  • ajax: före - strax före ajax-samtalet
  • ajax: lastning - före ajax-samtal, men efter att XmlHttpRequest-objekt skapats)
  • ajax: framgång - framgångsrikt ajax-samtal
  • ajax: misslyckande - misslyckades ajax-samtal
  • ajax: fullständig - slutförande av ajax-samtal (efter ajax: framgång och ajax: misslyckande)
  • ajax: efter - efter ajax-samtal skickas (anmärkning: inte efter att den returneras)

I vårt fall lägger vi till en händelseloggare i ajax: framgång händelse på våra raderingslänkar, och gör det borttagna inlägget blekna istället för att ladda om sidan. Vi lägger till följande JavaScript i vår application.js-fil.

 $ ('. delete_post'). binda ('ajax: framgång', funktion () $ (detta) .closest ('tr'). fadeOut (););

Vi måste också berätta för vår posts_controller att inte försöka göra en vy efter att det har slutförts radera inlägget.

 def förstöra @post = Post.find (params [: id]) @ post.destroy respond_to | format | format.html redirect_to (posts_url) format.js render: nothing => true avsluta

Nu när vi tar bort ett inlägg kommer det gradvis att blekna ut.


Slutsats

Tja, där har du det. Nu vet du hur man gör AJAX-samtal med hjälp av Rails 3 UJS. Medan de förklarade exemplen var enkla kan du använda samma teknik för att lägga till alla slags interaktivitet för ditt projekt. Jag hoppas att du håller med om att det är en stor förbättring jämfört med tidigare versioner, och att du ska prova på ditt nästa Rails-projekt.

Vilka tekniker använder du när du implementerar AJAX i Rails?