Arbeide med Intl

Internationalisering - noe du stadig hører utviklere snakker om, men sjelden ser faktisk folk bruker i praksis - får et spark i buksene med den nye ECMAScript Internationalization API. For øyeblikket støttes i Chrome 24, Chrome for Android, Firefox 29, IE 11 og Opera 15 (dessverre ingen Safari-støtte), gir det nye Intl namespace et sett med funksjonalitet for å legge til internasjonalisering i nummer, datoer og sortering. I denne artikkelen vil jeg demonstrere de viktigste funksjonene i Intl og få deg på veien for å vedta støtte for milliarder mennesker på Internett som bor utenfor ditt eget land!

Kjernefunksjoner

Intl namespace dekker tre hovedområder av funksjonalitet:

  • Formateringsnumre
  • Formatering datoer
  • Sortering av strenger

Innenfor hver av disse er forskjellige alternativer for å kontrollere både lokalene som brukes til formatering samt formateringsalternativer. For eksempel inkluderer tallformatteren støtte for håndtering av valuta. Datoformateren har opsjoner for hvilke deler av datoen som skal vises.

La oss ta en titt på noen få eksempler.

Vår søknad

Vår første applikasjon er en enkel dataregister. Det bruker AJAX til å hente et sett med data som inneholder datoer og tall. Først HTML:

Oppføring 1: test1.html:

          

Nåværende statistikk

Dato besøk

Legg merke til det tomme bordet. Det er her vi skal dumpe våre data. La oss nå se på JavaScript.

Oppføring 2: app1.js:

$ (dokument) .ready (funksjon () // få tabelldommen $ table = $ ("# stats tbody"); // nå, hent vår data fra api, som er falsk btw $ .getJSON .json "). gjort (funksjon (er) // iterate over statistikk og legg til tabell for (var i = 0; i < s.length; i++)  $table.append(""+s[i].date+""+s[i].views+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); ); ); 

Alt som koden gjør her, er å lage en AJAX-samtale til en fil og gjøre resultatet til dataene. Datafilen, stats.json, er bare et utvalg av ti hardkodede verdier. Her er en del av filen:

[ "Dato": "4/1/2013", "visninger": 938213,  "dato": "4/2/2013", "views": 238213, 

Som du kan se, er datoene formatert som måned / dato / år og tallene er bestått, som det er. Dette gjør akseptabelt:

Men merk at tallene er litt vanskelig å lese uten formatering. La oss begynne med å legge til noen formatering på tallene.

Legge til tallformatering

Følgende modifikasjoner kan ses i app2.js og testet med test2.html. Først vil jeg endre koden min for å ringe en ny funksjon, numberFormat:

$ Table.append ( "" + S [i] .date + "" + numberFormat (s [i] .views) + "");

Og her er den funksjonen:

funksjon numberFormat (n) // cache formatteren en gang hvis (window.Intl &&! window.numberFormatter) window.numberFormatter = window.Intl.NumberFormat (); hvis (window.numberFormatter) return window.numberFormatter.format (n);  ellers return n; 

Funksjonen begynner med å sjekke om Intl finnes som en del av vindu gjenstand. Hvis det gjør det, sjekker vi da for å se om vi har gjort formateringen før. De Intl objekt oppretter et formateringsobjekt som du kan bruke på nytt, og siden vi formaterer en rekke tall, vil vi bare lage den en gang. Det er akkurat det vi gjør så fort vi ser at vi trenger det også. Vi bryr oss ikke om noen alternativer for nå, bare for å holde det enkelt. Til slutt, hvis det ikke var støtte for Intl i det hele tatt, vi returnerer bare nummeret som det er. Resultatet er en betydelig forbedring, med minimal arbeid:

Kul! Så, hvordan tester vi andre språk? Du kan bli fristet til å sjekke nettleserinnstillingene dine. Alle nettlesere foretrekker språk, men dessverre endrer språket i nettleseren det er ikke nok. Endre det gjør påvirke hvordan nettleseren oppfører seg. 

Hvis du åpner dev-verktøyene dine og ser på nettverksforespørsler, kan du se at en overskrift som heter "Godta-Lanage"vil endres basert på innstillingene dine. Hvis du legger til fransk, for eksempel (jeg antar at du ikke er fransktalende), vil du se"fr"lagt til i denne overskriften. Men dette påvirker ikke Intl. I stedet må du endre operativsystemets språk og starte nettleseren på nytt. Dette er ikke så skummelt som det høres ut. Da jeg testet, var jeg bekymret for at hele operativsystemet mitt ville endres umiddelbart. Men i mine tester var jeg i stand til å endre språket, starte nettleseren min og se endringen. Jeg endret raskt tilbake. Intl formateringsfunksjonene gir deg mulighet til å overstyre gjeldende lokale og passere en i stedet.

Jeg endret søknaden slik at sluttbrukeren kunne spesifisere et språk via en rullegardin. Her er endringen gjort i HTML-koden. (Denne endringen kan bli funnet i test3.html)

Språkene jeg plukket var ganske vilkårlig. Neste - Jeg oppdaterte programkoden min for å lytte til endringer i denne nedgangen, samt å sjekke ønsket språk når du formaterer.

Oppføring 3: app3.js:

funksjon numberFormat (n) if (window.Intl) var lang = $ ("# langDropdown") .val (); hvis (lang === "") lang = navigator.language; var formatter = nytt vindu.Intl.NumberFormat (lang); returnere formatter.format (n);  ellers return n;  funksjon getStats () $ .getJSON ("stats.json"). ferdig (funksjon (er) // iterate over statistikk og legg til tabell for (var i = 0; i < s.length; i++)  $table.append(""+s[i].date+""+numberFormat(s[i].views)+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); );  $(document).ready(function()  //get the table dom $table = $("#stats tbody"); //notice changes to drop down $("#langDropdown").on("change", function(e)  $table.empty(); getStats(); ); getStats(); ); 

Starter nederst - merk at jeg har lagt til en enkel hendelsehandler for endringer i rullegardinmenyen. Når en forandring er oppdaget, tømmes tabellen og funksjonen getStats kjøres. Denne nye funksjonen oppsummerer bare AJAX-koden som ble brukt tidligere. Den virkelige forandringen er nå inne numberFormat. Jeg sjekker språket som er valgt, og hvis en av dem ble valgt, sender vi det som språk til NumberFormat konstruktør. Merk at hvis noe ikke ble valgt, standardiserer vi det navigator.language. Dette gir oss nå en måte å raskt teste forskjellige lokaliteter og se hvordan de gir tall.

Legge til datoformatering

Nå er det en perfekt tid å ta vare på den andre kolonnen av data - tallene. Jeg fulgte samme stil som før og la til en samtale til en ny funksjon, dateformat.

$ Table.append ( "" + dateformat (s [i] .date) + "" + numberFormat (s [i] .views) + "");

Og her er det dateformat (Du finner koden i app4.js, som brukes av test4.html):

funksjon dateFormat (n) // Brukes til datovisning var opts = ; opts.day = "numeric"; opts.weekday = "long"; opts.year = "numeric"; opts.month = "long"; hvis (window.Intl) var lang = $ ("# langDropdown") .val (); hvis (lang === "") lang = navigator.language; var formatter = nytt vindu.Intl.DateTimeFormat (lang, ops); n = ny dato (n); returnere formatter.format (n);  ellers return n;  

Dette ligner meget på tallformatering, bortsett fra denne gangen eksplisitt vi sender noen alternativer når vi lager formateringen. Alternativene angir både hvilke felt som er synlige i datoen, så vel som hvordan de ser ut. Hver del av en dato kan vises eller ikke, og hver har forskjellige alternativer. Alternativene inkluderer:

  • ukedag
  • era
  • år
  • måned
  • dag
  • time
  • minutt
  • sekund
  • timeZoneName

For en fullstendig liste over hvilke verdier du kan bruke, se MDN-dokumentasjonen for DateTimeFormat, men som et eksempel kan måneder vises som et tall eller i forskjellige tekstformer. Så hva skaper dette? Her er den engelske versjonen:

Og her er det på fransk:

Du lurer kanskje på - hva dekker plasseringen av hvert felt? Så vidt jeg kan fortelle, har du ingen kontroll over dette. Du kan selvfølgelig opprette flere formater og deretter kombinere dem sammen, men ved hjelp av en formatter er feltets layout drevet av intern logikk. Hvis du slår av dagen i måneden, for eksempel, er det hva du får: april 2013 mandag. Hvorfor? Ærlig talt har jeg ingen anelse.

Til slutt - merk at du må sende en datavare, ikke en streng, til formateringen. Du kan se hvor jeg bruker datakonstruktøren i formateringen for å analysere min strengbaserte dato. Dette er - litt løs - så hold dette i bakhodet når du bruker denne funksjonaliteten.

Vis meg pengene

Valutaformatering er ikke et eget objekt, men snarere en valgfri bruk av tallformateren. For den neste demonstrasjonen har vi opprettet en ny datafil, stats2.json, og lagt til en "salg" kolonne til våre data. Her er et eksempel:

 "Dato": "4/1/2013", "visninger": 938213, "salg": 3890.21,  "dato": "4/2/2013", "visninger": 238213 "" salgs: 9890,10 

Kolonnen ble lagt til HTML (test5.html), lagt til i JavaScript iterating over radene av data (se app5.js), og sendt til en ny funksjon som heter currencyFormat. La oss se på det.

funksjon valutaFormat (n) var opts = ; opts.style = "valuta"; opts.currency = "USD"; hvis (window.Intl) var lang = $ ("# langDropdown") .val (); hvis (lang === "") lang = navigator.language; var formatter = nytt vindu.Intl.NumberFormat (lang, ops); returnere formatter.format (n);  ellers return n;  

Vise tall som valuta krever to valgfrie verdier. Først en stil med "valuta", og deretter valutatype. Andre alternativer (som hvordan du kan vise navnet på valutaen) finnes også. Her kommer den delen som kan trekke deg opp litt. Du spesifiser valuta typen. 

Du kan tenke - hvordan finner jeg valutaen for alle mulige verdier? De mulige verdiene er basert på en spec (http://www.currency-iso.org/en/home/tables/table-a1.html) og i teorien kan du analysere XML-en, men du vil ikke gjøre det. Grunnen til at det er ganske opplagt, men jeg kan ærlig si at jeg glemte i utgangspunktet også. Du vil ikke bare vise et bestemt nummer i en lokal valuta. Hvorfor? Fordi ti dollar amerikansk er absolutt ikke det samme som ti dollar i pesos. Det er ganske opplagt og forhåpentligvis er jeg den eneste personen som glemmer det.

Ved å bruke koden ovenfor kan vi se følgende resultater i den franske locale. Legg merke til hvordan tallene er formatert riktig for lokalene, og valutasymbolet er plassert etter nummeret.

Sortering med Collator

For vårt siste eksempel, ser vi på samle konstruktør. Kollatører lar deg håndtere tekst sortering. Mens noen språk følger et enkelt A til Z-bestillingssystem, har andre språk forskjellige regler. Og selvfølgelig blir ting enda mer interessante når du begynner å legge til aksenter. Kan du si, for sikker, om ä kommer etter en? Jeg vet at jeg ikke kan. Kollatorkonstruksjonen tar en rekke argumenter for å hjelpe til med å spesifisere nøyaktig hvordan den skal sortere, men standard vil trolig fungere bra for deg.

For dette eksempelet har vi bygget en helt ny demo, men en som ligner på de tidligere eksemplene. I test6.html, Du kan se et nytt bord, for studenter. Vår nye kode vil laste opp en JSON-pakke med studenter og sortere dem på klienten. JSON-dataene er ganske enkelt en rekke navn, så jeg hopper over et utdrag. La oss se på programlogikken.

Oppføring 4: app6.js:

funksjon sorterer (x, y) if (window.Intl) var lang = $ ("# langDropdown") .val (); hvis (lang === "") lang = navigator.language; returner window.Intl.Collator (lang) .compare (x, y);  ellers return x.localeCompare (y);  funksjon getStudents () $ .getJSON ("students.json"). gjort (funksjon (er) // iterate over statistikk og legg til tabell s.sort (sorterer); for (var i = 0; i < s.length; i++)  $table.append(""+s[i]+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); );  $(document).ready(function()  //get the table dom $table = $("#students tbody"); //notice changes to drop down $("#langDropdown").on("change", function(e)  $table.empty(); getStudents(); ); getStudents(); ); 

Som jeg sa, er denne koden ganske lik de forrige eksemplene, så fokusere på getStudents først. Den avgjørende linjen her er: s.sort (sorter). Vi bruker den innebygde funksjonen for arrays å gjøre sortering via en tilpasset funksjon. Denne funksjonen vil bli bestått to ting å sammenligne og må returnere -1, 0, eller 1 å representere hvordan de to elementene skal sorteres. La oss nå se sorteringen.

Hvis vi har en Intl objekt, vi lager en ny samle (og igjen, vi lar deg passere i en lokalitet) og så løper vi sammenligne funksjon. Det er det. Som sagt, er det muligheter for å endre hvordan ting sorteres, men vi kan bruke standardinnstillingene. Fallback er localeCompare, som også vil forsøke å bruke lokal spesifikk formatering, men har (i dette skjemaet) litt bedre støtte. Vi kan også sjekke for den støtten og legge til en ekstra tilbakebetaling for egentlig god støtte, men jeg forlater det for deg som en øvelse.

Vi har også endret frontenden til å bruke svensk som språk. Jeg gjorde dette fordi den utmerkede MDN-dokumentasjonen viste at det var en god måte å se sorteringen i aksjon. Her er den engelske typen av våre studentnavn:

Og her er det på svensk:

Legg merke til hvordan eietest er sortert annerledes. Beklager, jeg kunne ikke tenke på et navn som begynte med ä.

Wrap Up

Alt i alt, den Intl klassen gir noe veldig enkle måter å legge til landsspesifikke formatering til koden din. Dette er absolutt noe du kan finne nå, sannsynligvis i noen få tusen forskjellige JavaScript-biblioteker, men det er flott å se nettleserprodusentene legge til støtte direkte i språket selv. Mangelen på iOS-støtte er en bummer, men forhåpentligvis vil den bli lagt til snart.

Takk går til det utmerkede Mozilla Developer Network for sin gode Intl-dokumentasjon.