Bruke Diskret JavaScript og AJAX med Rails 3

Som nevnt i min tidligere Ruby on Rails-opplæring, er Unobtrusive JavaScript (UJS) en av de kuleste nye funksjonene i Rails 3. UJS tillater Rails-generert kode å være mye renere, bidrar til å skille JavaScript-logikken fra HTML-oppsettene dine, og uncouples Rails fra Prototype JavaScript-biblioteket. I denne opplæringen skal vi se på disse funksjonene og lære å bruke dem i et enkelt Rails 3-program.


Bakgrunn: Hva er diskret JavaScript?

For å starte, hva er UJS? Bare UJS er JavaScript som er skilt fra HTML-oppslaget ditt. Den enkleste måten å beskrive UJS er med et eksempel. Ta en onclick event handler; vi kunne legge til det påtrengende:

 link

Eller vi kunne legge det på diskusjon ved å legge hendelsen til lenken (ved hjelp av jQuery i dette eksempelet):

 link 

Som nevnt i min introduksjon, har denne andre metoden en rekke fordeler, inkludert enklere feilsøking og renere kode.

"Rails 3, derimot, er JavaScript-rammeverk agnostisk. Med andre ord kan du bruke JavaScript-rammeverket ditt, forutsatt at en Rails UJS-implementering eksisterer for det rammene."

Frem til versjon 3 genererte Ruby on Rails påtrengende JavaScript. Den resulterende koden var ikke ren, men enda verre, den var tett koblet til Prototype JavaScript-rammeverket. Dette betydde at med mindre du opprettet et plugin eller hacked Rails, måtte du bruke Prototype-biblioteket med Rails JavaScript-hjelpemetoder.

Rails 3, derimot, er JavaScript-rammeverk agnostisk. Med andre ord kan du bruke JavaScript-rammeverket ditt, forutsatt at en Rails UJS-implementering eksisterer for det rammeverket. De nåværende UJS-implementasjonene omfatter følgende:

  • Prototype (standard)
  • jQuery
  • MooTools

Rails 3 implementerer nå all sin JavaScript Helper-funksjonalitet (AJAX sender, bekreftelsesanbefalinger, osv.) Diskret ved å legge til følgende HTML 5 egendefinerte attributter til HTML-elementer.

  • data-metode - REST-metoden som skal brukes i skjemainnlegg.
  • data-bekreft - bekreftelsesmeldingen som skal brukes før du utfører noen handlinger.
  • data-fjernkontroll - hvis sant, send inn via AJAX.
  • data-deaktiver-med - deaktiverer skjemaelementer under skjemainnlevering

For eksempel, denne linken taggen

 Ødelegge

ville sende en AJAX slett forespørsel etter å ha spurt brukeren "Er du sikker?".

Du kan forestille deg hvor mye vanskeligere å lese det ville være hvis alt det JavaScript var inline.

Nå som vi har vurdert UJS og hvordan Rails implementerer UJS, la oss sette opp et prosjekt og se på enkelte spesifikke applikasjoner. Vi bruker jQuery-biblioteket og UJS-implementeringen i denne opplæringen.


Trinn 1: Sette opp prosjektet

Siden vi oppretter et nytt prosjekt fra begynnelsen, er det første vi må gjøre å opprette prosjektet ved å skrive følgende:

 skinner ny blogg - skip-prototype

Legg merke til at jeg instruerer Rails for å hoppe over prototypens JavaScript-fil, siden jeg skal bruke jQuery-biblioteket.

La oss starte serveren bare for å sikre at alt ser ut til å fungere.

Og, voila!

Nå som vi har satt opp prosjektet, må vi legge til jQuery og jQuery UJS til prosjektet vårt. Du er fri til å organisere JavaScript, men du vil, men Rails-konvensjonen for strukturering av JavaScript-filene dine er som følger (alle disse filene går offentlig / javascripts):

  • Framework JavaScript-fil (jquery.js, prototype.js eller mootools.js)
  • rails.js - koden som implementerer skinner UJS (for hvilket rammeverk du har valgt)
  • application.js - din applikasjon JavaScript

Hvis du ikke allerede har lastet ned, må du laste ned jquery.js (eller referere til en CDN) og rails.js og inkludere dem i din offentlige / javascripts katalog.

Det siste vi må gjøre for å komme i gang, er faktisk å fortelle Rails å inkludere disse js-filene på hver av våre sider. For å gjøre dette åpner du application.rb i konfigurasjonsmappen din og legger til følgende linje

 config.action_view.JavaScript_expansions [: defaults] =% w (jquery rails søknad)

Dette konfigurasjonselementet forteller Rails å inkludere de tre JavaScript-filene som er nevnt ovenfor som standard.

Alternativt kan du hente jQuery fra en CDN (dvs. http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js) ved å manuelt inkludere en skriptetikett som peker på riktig sted. Hvis du gjør dette, må du fjerne "jquery" fra konfigurasjonselementet JavaScript_expansions.


Trinn 2: Genererer noen kode

For å demonstrere skinnene UJS-funksjonalitet må vi først ha kode for å jobbe med. For denne demoen skal vi bare ha et enkelt Post-objekt. La oss generere det nå

 skinner generere stillas Postnavn: strengtittel: strenginnhold: tekst

Og så la oss migrere databasen vår for å lage innleggstabellen.

 rake db: migrere

Ok, det er bra å gå! Hvis vi navigerer til http: // localhost: 3000 / innlegg / ny, Vi bør se et skjema for å opprette et nytt innlegg.

Ok, det fungerer alt! La oss nå grave inn og se hvordan du bruker UJS- og AJAX-funksjonaliteten bakket i Rails.


Trinn 3: Legge til AJAX

Nå som alle nødvendige JavaScript-filer er inkludert, kan vi faktisk begynne å bruke Rails 3 for å implementere noen AJAX-funksjonalitet. Selv om du kan skrive alle de egendefinerte JavaScript som du vil ha, gir Rails noen gode innebygde metoder som du kan bruke til å enkelt utføre AJAX-anrop og andre JavaScript-handlinger.

La oss se på et par vanlige hjelpelister og JavaScript de genererer

AJAX Form Submission og Javascript ERB Files

Hvis vi ser på innleggets skjema, kan vi se at når vi oppretter eller redigerer et innlegg, sendes skjemaet manuelt og deretter blir vi omdirigert til en skrivebeskyttet visning av innlegget. Hva om vi ønsket å sende det skjemaet via AJAX i stedet for å bruke en manuell innsending?

Rails 3 gjør det enkelt å konvertere alle former til AJAX. Først åpner du _form.html.erb delvis i app / visninger / innlegg, og endre første linje fra:

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

til

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

Før Rails 3, legger du til : remote => true ville ha generert en haug med inline JavaScript inne i formeltaggen, men med Rails 3 UJS er den eneste endringen tillegg av et HTML 5-tilpasset attributt. Kan du få øye på det?

 

Attributtet er data-fjern = "true", og Rails UJS JavaScript binder til noen former med det attributtet og sender dem via AJAX i stedet for en tradisjonell POST.

Det er alt som trengs for å gjøre AJAX sende, men hvordan utfører vi tilbakering etter at AJAX-samtalen returnerer?

Den vanligste måten å håndtere en retur fra et AJAX-anrop er gjennom bruk av JavaScript ERB-filer. Disse fungerer akkurat som dine normale ERB-filer, men inneholder JavaScript-kode i stedet for HTML. La oss prøve det ut.

Det første vi må gjøre er å fortelle vår kontroller hvordan du svarer på AJAX-forespørsler. I posts_controller.rb (app / controllers) kan vi fortelle vår kontroller å svare på en AJAX-forespørsel ved å legge til

 format.js

i hver response_to block at vi skal ringe via AJAX. For eksempel kan vi oppdatere opprettingsaksjonen slik at den ser slik ut:

 def create @post = Post.new (params [: post]) reply_to | format | hvis @ post.save format.html redirect_to (@post,: notice => 'Post opprettet.') format.js else format.html render: action => "new" format.js slutten slutten

Fordi vi ikke angav noen alternativer i answer_to-blokken, svarer Rails til JavaScript-forespørsler ved å laste inn en .js ERB med samme navn som kontrolleren handling (create.js.erb, i dette tilfellet).

Nå som vår kontroller vet hvordan man håndterer AJAX-anrop, må vi lage våre synspunkter. For gjeldende eksempel, legg til create.js.erb i din app / visninger / innlegg katalogen. Denne filen blir gjengitt og JavaScript inni vil bli utført når samtalen avsluttes. For nå overskriver vi bare skjemaetiketten med tittelen og innholdet i blogginnlegget:

 $ ( 'Body'). Html ("

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

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

Nå hvis vi oppretter en ny Post, får vi følgende på skjermen. Suksess!

Fordelen med denne metoden er at du kan sperre rubin kode som du har satt opp i kontrolleren din med JavaScript, noe som gjør det veldig enkelt å manipulere visningen din med resultatene av en forespørsel.

AJAX-tilbakeringinger ved hjelp av egendefinerte JavaScript-hendelser

Hver Rails UJS-implementering gir også en annen måte å legge til tilbakeringinger til våre AJAX-samtaler - tilpassede JavaScript-hendelser. La oss se på et annet eksempel. På vårt innleggs indeksvisning (http: // localhost: 3000 / innlegg /), kan vi se at hvert innlegg kan slettes via en slettekobling.

La oss AJAXify vår lenke ved å legge til: remote => sann og i tillegg gi den en CSS klasse slik at vi enkelt kan finne denne POSTen ved hjelp av en CSS velger.

 <%= link_to 'Destroy', post, :confirm => 'Er du sikker?',: Metode =>: slett,: remote => true,: class => 'delete_post'%>

Hvilket gir følgende utgang:

 Ødelegge

Hver skinne UJS AJAX-samtale gir seks tilpassede hendelser som kan knyttes til:

  • ajax: før - rett før ajax-anrop
  • ajax: lasting - før ajax-anrop, men etter at XmlHttpRequest-objektet er opprettet)
  • ajax: suksess - vellykket ajax samtale
  • ajax: svikt - feilet ajax-anrop
  • ajax: komplett - fullføring av ajax-anrop (etter ajax: suksess og ajax: feil)
  • ajax: etter - etter at ajax-samtalen er sendt (merknad: ikke etter at den returnerer)

I vårt tilfelle legger vi til en hendelseslytter til ajax: suksess hendelse på våre slettede koblinger, og gjør det slettede innlegget fadet ut, snarere enn å laste siden på nytt. Vi legger til følgende JavaScript i vår application.js-fil.

 $ ('. delete_post'). bind ('ajax: suksess', funksjon () $ (dette) .closest ('tr'). fadeOut (););

Vi må også fortelle våre posts_controller å ikke prøve å gjengi en visning etter at det er ferdig med å slette innlegget.

 def ødelegge @post = Post.find (params [: id]) @ post.destroy respond_to do | format | format.html redirect_to (posts_url) format.js render: nothing => true avslutte

Nå når vi sletter et innlegg, vil det gradvis falme ut.


Konklusjon

Vel, det har du det. Nå vet du hvordan du lager AJAX-anrop ved hjelp av Rails 3 UJS. Mens eksemplene som ble forklart, var enkle, kan du bruke disse samme teknikkene for å legge til alle slags interaktivitet for prosjektet ditt. Jeg håper du er enig i at det er en stor forbedring i forhold til tidligere versjoner, og at du vil prøve det på ditt neste Rails-prosjekt.

Hvilke teknikker bruker du når du implementerer AJAX i Rails?