Lucrul cu Intl

Internaționalizarea - ceea ce auziți în mod constant dezvoltatorii vorbind, dar rar văd de fapt pe cei care le folosesc în practică - obține o lovitură de pantaloni cu noul API Interminaționalizare ECMAScript. Actualmente acceptat în Chrome 24, Chrome pentru Android, Firefox 29, IE 11 și Opera 15 (din păcate nu există suport pentru Safari), noul spațiu de nume Intl oferă un set de funcționalități pentru a adăuga internaționalizarea numerelor, datelor și sortare. În acest articol voi demonstra principalele caracteristici ale Intl și vă voi face pe calea adoptării de sprijin pentru miliardele de oameni de pe Internet care trăiesc în afara țării dvs.!

Caracteristici de baza

Spațiul de nume Intl acoperă trei domenii principale de funcționalitate:

  • Formatarea numerelor
  • Date de formatare
  • Sortarea șirurilor

În cadrul fiecăreia dintre acestea există diferite opțiuni pentru controlul atât a localizărilor utilizate pentru formatare, cât și a opțiunilor de formatare. De exemplu, formatorul de numere include suport pentru manipularea valutei. Formatorul de date are opțiuni pentru ce părți ale datei să fie afișate.

Să aruncăm o privire la câteva exemple.

Cererea noastră

Prima noastră aplicație este un reporter simplu de date. Utilizează AJAX pentru a prelua un set de date care conțin date și numere. În primul rând, codul HTML:

Listarea 1: test1.html:

          

Statistici actuale

Data vizite

Luați notă de tabelul gol. Acolo vom elimina datele noastre. Acum, să aruncăm o privire la JavaScript.

Lista 2: app1.js:

$ (document) .ready (functie () // obtineti tabela dom $ table = $ ("# stats tbody"); // acum obtineti datele din api, care este fake btw $ .getJSON (funcția (s) // iterați peste statistici și adăugați la tabel pentru (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); ); ); 

Tot ceea ce face codul aici, este de a face un apel AJAX la un fișier și de a face rezultatul la date. Fișierul de date, stats.json, este pur și simplu o serie de zece valori codate greu. Iată o parte a fișierului:

[ "data": "4/1/2013", "opinii": 938213,  "data": "4/2/2013", "vizualizări": 238213, 

După cum puteți vedea, datele sunt formatate ca luna / data / an iar numerele sunt trecute, așa cum este. Acest lucru face acceptabil:

Dar rețineți că numerele sunt greu de citit fără formatare. Să începem prin adăugarea unor formate la numere.

Adăugarea formatării de numere

Următoarele modificări pot fi văzute în app2.js și testat cu test2.html. Mai întâi, îmi modific codul pentru a apela o funcție nouă, numberFormat:

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

Și aici este această funcție:

funcția numberFormat (n) // cache formatatorul o dată dacă (window.Intl &&! window.numberFormatter) window.numberFormatter = window.Intl.NumberFormat (); dacă (window.numberFormatter) return window.numberFormatter.format (n);  altceva return n; 

Funcția începe prin a verifica dacă Intl există ca parte a fereastră obiect. În caz contrar, vom verifica dacă am făcut formatorul înainte. Intl obiect creează un obiect de formatare pe care îl puteți reutiliza și, din moment ce formatem o grămadă de numere, dorim doar să îl creăm o singură dată. Care este exact ceea ce facem de îndată ce vedem că avem nevoie și de noi. Nu ne deranjeaza acum nici o optiune, doar ca sa fie simplu. În cele din urmă, dacă nu ar exista nici un sprijin Intl la toate, vom returna numărul așa cum este. Rezultatul este o îmbunătățire semnificativă, cu o muncă minimă:

Rece! Deci, cum să testați alte limbi? Este posibil să fiți tentat să verificați setările browserului. Toate browserele au o preferință pentru limbă, dar, din păcate, schimbarea limbii în browser nu este de ajuns. Schimbarea acesteia face influența modul în care se comportă browserul. 

Dacă deschideți instrumentele dvs. dev și vedeți cererile de rețea, puteți vedea că un antet numit "Acceptați-Lanage"se va schimba în funcție de setările dvs. Dacă adăugați franceză, de exemplu (presupun că nu sunteți un vorbitor nativ francez), veți vedea"fr"adăugat la acest antet, dar acest lucru nu are impact Intl. În schimb, trebuie să schimbați limba sistemului de operare și să reporniți browserul. Aceasta este nu la fel de înfricoșătoare. Când am testat, am fost îngrijorat că întregul meu sistem de operare se va schimba imediat. Dar, în testele mele, am reușit să schimb limba, să repornez browserul și să văd schimbarea. M-am întors repede. Funcțiile de formator din Intl vă permit să înlocuiți locația actuală și să introduceți unul în loc.

Am modificat aplicația pentru a permite utilizatorului final să specifice o limbă prin intermediul unei drop-down. Iată modificarea făcută în HTML. (Această modificare poate fi găsită în test3.html)

Limbile pe care le-am ales erau destul de arbitrare. Înainte - mi-am actualizat codul aplicației pentru a asculta modificări la această meniuri și pentru a verifica localizarea dorită la formatare.

Listarea 3: app3.js:

funcția numberFormat (n) if (window.Intl) var lang = $ ("# langDropdown") val (); dacă (lang === "") lang = navigator.language; var formatter = fereastră nouă.Intl.NumărFormat (lang); retur formatter.format (n);  altceva return n;  funcția getStats () $ .getJSON ("stats.json") făcut (funcția (s) // iterați peste statistici și adăugați la tabel pentru (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(); ); 

Începând din partea de jos - rețineți că am adăugat un manipulator simplu de evenimente pentru modificarea drop-down. Când se detectează o modificare, tabela este golită și funcția getStats se execută. Această nouă funcție absoarbe pur și simplu codul AJAX folosit anterior. Schimbarea reală este acum în numberFormat. Am verificat limba selectată și dacă unul dintre ei a fost ales, trecem ca localizarea la NumberFormat constructor. Rețineți că dacă ceva nu a fost ales, ne-am implicit navigator.language. Acest lucru ne oferă acum o modalitate de a testa rapid localizări diferite și de a vedea cum fac numere.

Adăugarea formatării datei

Acum este momentul perfect pentru a avea grijă de cealaltă coloană de date - numerele. Am urmat același stil ca înainte și am adăugat un apel la o funcție nouă, formatul datei.

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

Și aici este formatul datei (Puteți găsi codul în app4.js, care este folosit de către test4.html):

function dateFormat (n) // Folosit pentru afișarea date var opts = ; opts.day = "numeric"; opts.weekday = "lung"; opts.year = "numeric"; opts.month = "lung"; dacă (window.Intl) var lang = $ ("# langDropdown"). Val (); dacă (lang === "") lang = navigator.language; var formatter = fereastră nouă.Intl.DateTimeFormat (lang, opts); n = data nouă (n); retur formatter.format (n);  altceva return n;  

Acest lucru este foarte asemănător cu formatarea numărului, cu excepția faptului că în acest moment suntem în mod explicit să trecem câteva opțiuni când creăm formatorul. Opțiunile specifică atât câmpurile care sunt vizibile în dată, cât și cum arată acestea. Fiecare parte a unei date poate fi afișată sau nu, și fiecare are opțiuni diferite. Opțiunile includ:

  • zi de lucru
  • eră
  • an
  • lună
  • zi
  • ora
  • minut
  • al doilea
  • timeZoneName

Pentru o listă completă a valorilor pe care le puteți utiliza, consultați documentația MDN pentru DateTimeFormat, dar, ca exemplu, luni pot fi afișate ca un număr sau în diferite forme textuale. Deci, ce crează acest lucru? Iată versiunea în limba engleză:

Și aici este în franceză:

S-ar putea să vă întrebați - ce acoperă locația fiecărui domeniu? Din câte vă pot spune, nu aveți control asupra acestui lucru. S-ar putea, desigur, să creați mai mulți formatori și apoi să le combinați, dar folosind un formatator, aspectul câmpurilor este condus de logica internă. Dacă dezactivați ziua din lună, de exemplu, iată ce obțineți: aprilie 2013 luni. De ce? Sincer, nu am idee.

În cele din urmă - rețineți că trebuie să transmiteți formatatorului o valoare de dată, nu un șir. Puteți vedea unde folosesc constructorul de date din formatator pentru a analiza data pe care am creat-o. Acest lucru este - un pic pierdut - deci ține cont de acest lucru atunci când utilizați această funcție.

Arata-mi banii

Formatul de valută nu este un obiect separat, ci mai degrabă o utilizare opțională a formatorului de numere. Pentru următoarea demo, am creat un nou fișier de date, stats2.json, și a adăugat o coloană "vânzări" la datele noastre. Iată un exemplu:

 "Data": "4/1/2013", "opinii": 938213, "vânzări": 3890.21,  "data": "4/2/2013", "opinii": 238213, "vânzări": 9890.10 

Coloana a fost adăugată la codul HTML (test5.html), adăugat în JavaScript iterating peste rândurile de date (a se vedea app5.js), și a trecut la o nouă funcție numită currencyFormat. Să ne uităm la asta.

funcția valutăFormat (n) var opts = ; opts.style = "valută"; opts.currency = "USD"; dacă (window.Intl) var lang = $ ("# langDropdown"). Val (); dacă (lang === "") lang = navigator.language; var formatter = fereastră nouă.Intl.NumărFormat (lang, opts); retur formatter.format (n);  altceva return n;  

Afișarea numerelor ca valute necesită două valori opționale. În primul rând, un stil de "valută", și apoi tipul de monedă. Sunt disponibile și alte opțiuni (cum ar fi cum se afișează numele monedei). Aici vine partea care te poate face sa te desparti putin. Tu trebuie sa specificați tipul de monedă. 

S-ar putea să vă gândiți - cum în ce naiba îmi dau seama de tipul de valută pentru toate valorile posibile? Valorile posibile se bazează pe o specificație (http://www.currency-iso.org/en/home/tables/table-a1.html) și teoretic ai putea să le analizezi XML-ul, dar nu vrei să faci asta. Motivul pentru care este destul de evident, dar pot spune sincer că am uitat și inițial. Nu doriți să redeschideți doar un anumit număr într-o monedă specifică locale. De ce? Pentru că zece dolari american este cu siguranță nu la fel ca zece dolari în peso. E destul de evident și sper că sunt singura persoană care să uite asta.

Folosind codul de mai sus, putem vedea următoarele rezultate în limba franceză. Rețineți modul în care numerele sunt formatate corect pentru localizare, iar simbolul valută este plasat după număr.

Sortare cu Collator

Pentru exemplul nostru final, ne vom uita la Collator constructor. Colaboratorii vă permit să gestionați sortarea textului. În timp ce unele limbi urmează un simplu sistem de comandă de la A la Z, alte limbi au reguli diferite. Și, desigur, lucrurile devin și mai interesante atunci când începeți să adăugați accente. Poți să spui, sigur, dacă vine după un? Știu că nu pot. Constructorul de compilatoare ia un număr de argumente pentru a-l ajuta să specifice exact modul în care ar trebui să se sorteze, dar implicit va funcționa probabil bine pentru dvs..

Pentru acest exemplu, am construit o demonstrație complet nouă, dar una asemănătoare cu exemplele anterioare. În test6.html, puteți vedea o masă nouă, pentru Studenți. Noul cod va încărca un pachet JSON de elevi și apoi le sortează pe client. Datele JSON sunt pur și simplu o serie de nume, așa că voi trece prin afișarea unui extras. Să ne uităm la logica aplicației.

Lista 4: app6.js:

funcția sortare (x, y) if (window.Intl) var lang = $ ("# langDropdown"). dacă (lang === "") lang = navigator.language; retur fereastra.Intl.Collator (lang) .compare (x, y);  altceva return x.localeCompare (y);  funcția getStudents () $ .getJSON ("students.json") făcut (funcția (s) // iterați peste statistici și adăugați la tabela s.sort (sorter); < 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(); ); 

Așa cum am spus, acest cod este destul de similar cu exemplele anterioare, deci concentrați-vă pe getStudents primul. Linia crucială aici este: s.sort (sorter). Folosim funcția construită pentru a face sortarea prin intermediul unei funcții personalizate. Această funcție va fi trecută cu două lucruri de comparat și trebuie să se întoarcă -1, 0, sau 1 pentru a reprezenta modul în care cele două elemente ar trebui sortate. Acum, să ne uităm la sortare.

Dacă avem un Intl obiect, noi creăm un nou Collator (și din nou, vă permitem să treceți într-o localizare) și apoi rulați comparaţie funcţie. Asta e. Așa cum am spus, există opțiuni pentru a modifica modul în care lucrurile sunt sortate, dar putem folosi setările implicite. Adevărul este localeCompare, care va încerca, de asemenea, să utilizeze formatarea specifică locale, dar are (puțin sub această formă) un suport ușor mai bun. Am putea verifica și sprijinul respectiv și adăugați încă o rezervă într-adevăr sprijin bun, dar o să las asta pentru tine, ca un exercițiu.

De asemenea, am modificat partea frontală pentru a folosi limba suedeză ca limbă. Am făcut acest lucru pentru că documentația excelentă a MDN a arătat că a fost o modalitate bună de a vedea sortarea în acțiune. Iată numele englezesc al studenților noștri:

Și aici este în suedeză:

Rețineți modul în care ätest este sortat diferit. (Ne pare rău, nu m-am gândit la un nume care a început cu a.)

Învelire

În ansamblu, Intl clasa oferă unele foarte moduri simple de a adăuga formatarea specifică locale la codul dvs. Acesta este cu siguranță un lucru pe care îl puteți găsi acum, probabil în câteva mii de biblioteci diferite de JavaScript, dar este minunat să vedeți producătorii de browsere adăugând direct suport în limbajul în sine. Lipsa suportului pentru iOS este un bummer, dar sperăm că va fi adăugat în curând.

Vă mulțumim pentru excelenta rețea Mozilla Developer pentru excelenta documentație Intl.