Programarea cu Yii2 Utilizarea Ajax

Ce veți crea

Dacă întrebiți "Ce este Yii?", Verificați Introducere în Cadrul Yii, care examinează beneficiile Yii și include o prezentare generală a lui Yii 2.0, lansat în octombrie 2014.

În această programare cu seria Yii2, ghid direct cititorii în folosirea cadrului Yii2 pentru PHP. În acest tutorial, vom explora implementarea paginilor interactive folosind Ajax. În mod specific, voi evidenția utilizarea Ajax-ului în două domenii ale aplicației Planificator de întâlniri, despre care scriu în paralel seria Building Your Startup.

În primul rând, vom examina modul în care încărcăm o hartă Google pe pagină ca răspuns la intrarea unui anumit loc. Așa cum am arătat mai jos, după ce intru Pruncul Bistro și faceți clic pe întoarcere, harta la dreapta se încarcă dinamic fără o reîmprospătare a paginii.

În al doilea rând, vă voi arăta cum înregistrăm schimbările pe care un utilizator le face la o întâlnire în timpul fazei de planificare. Planificatorul de întâlniri facilitează participanților să își identifice locurile preferate și data și să aleagă ultima dată.

Ajax face procesul mult mai ușor și mai rapid, permițând utilizatorilor să alunece un număr de comenzi de comutare pentru a indica preferințele lor fără a fi necesară reîmprospătarea paginii.

Doar un memento, eu particip la comentariile de mai jos. Sunt interesat în special dacă aveți abordări diferite, idei suplimentare sau doriți să sugerați subiecte pentru tutoriale viitoare. Dacă aveți o sugestie de întrebare sau subiect, vă rugăm să postați mai jos. Puteți să mă contactați și pe Twitter @reifman direct.

Utilizarea lui Ajax cu Yii

De DanielSHaischt, prin intermediul Wikimedia Commons, CC BY-SA 3.0

Dacă începeți doar cu Ajax și doriți să începeți încet, Terenul de joacă Yii are două exemple simple de Ajax, care vă pot ajuta să revizuiți. Unul modifică textul pe o pagină prin Ajax, iar altul încarcă răspunsul într-un formular pe aceeași pagină, ambele fără reîmprospătare, fiecare cuprinzând exemple detaliate de cod.

Să ne aruncăm în cele două exemple principale. Puteți găsi toate sursele pentru aceste exemple în depozitul de coduri Planificator de întâlniri de la GitHub.

Afișarea interactivă a Google Maps

Construirea formularului de intrare

Atunci când se încarcă inițial formularul Creare locație (/frontend/views/place/create_place_google.php), acesta include widget-ul de căutare Google Live:

Integrarea API-ului JavaScript Google Places

Formularul încarcă biblioteca JavaScript Google Maps și o conectează la câmpul de introducere a casetei de căutare:

$ gpJsLink = 'https://maps.googleapis.com/maps/api/js?' . http_build_query (array ('cheie' => Yii :: $ app-> params ['google_maps_key'], 'biblioteci' => 'locuri',)); echo $ this-> registerJsFile ($ gpJsLink); $ options = '"types": ["establishment"], "componentRestrictions": "country": "us"'; echo $ this-> registerJs ("(functie () var input = document.getElementById ('loc-searchbox'); var opțiuni = $ opțiuni; căutarebox = noi google.maps.places.Autocomplete (input, options); ("loc");) (); ", \ yii \ web \ View :: POS_END);

Formularul parțial _formPlaceGoogle.php include câteva câmpuri ascunse în care rezultatele de pe hartă pot fi stocate înainte de trimiterea întregii pagini, precum și div div ascuns pentru afișarea hărții prin Ajax.

utilizați frontend \ assets \ MapAsset; MapAsset :: registru ($ acest); ...      ... 

Tabelul Place Planner pentru întâlniri stochează numele Google, place_id, locația, site-ul web, vecinătatea și adresa completă pentru utilizare în întreaga aplicație.

MapAsset inclus mai sus încarcă fișierul nostru create_place.js care funcționează între Google și formularul nostru; în principiu, gestionează transmiterea și răspunsul datelor prin Ajax.

Ajax noastre Gestionarea JavaScript 

Vă voi îndruma prin create_place.js în bucăți. Mai întâi, există setupListeners (), numită de forma părintească:

funcția () // searchbox este var pentru obiectul google places creat pe pagina google.maps.event.addListener (caseta de căutare, 'place_changed', function () var place = searchbox.getPlace (); ! // informează utilizatorul că un loc nu a fost găsit și returnat. retur; altfel // migrează datele JSON de pe Google în câmpuri de formă ascunse populateResult (loc, model);); var loc_input = document.getElementById (model + '- căsuță de căutare); google.maps.event.addDomListener (loc_input, 'keydown', funcția (e) if (e.keyCode == 13) e.preventDefault ();); 

Pe măsură ce utilizatorul începe să scrie, widgetul creează opțiuni tiphead pentru locurile din lumea reală, iar evenimentul place_changed este procesat cu fiecare apăsare de tastă. Tasta în jos ascultător de mai sus împiedică trimiterea formularului de chei de returnare (ASCII 13 sau 0xD pentru dvs.).

Iată cum arată cum scrieți. Intru Prună pentru Bistro de prune:

Colectarea hărții rezultate și a datelor sale

Dacă persoana a selectat introduceți sau faceți clic pe un loc din meniul derulant, atunci populateResult () se numește; dacă nu, nu facem nimic. 

funcția populateResult (loc, model) // muta JSON recuperarea datelor de la Google la câmpurile formate ascunse // astfel încât Yii2 poate posta datele $ ('#' + model + '- locație) val (JSON.stringify (place [ geometrie '] [' locația "])); $ ( '#' + Model de + '- google_place_id') val (locul [ 'place_id']);. $ ( '#' + Model de + '- full_address') val (locul [ 'formatted_address']);. $ ( '#' + Modelul + '- site-ul') val (locul [ 'site']);. $ ( '#' + Modelul + '- vecinătate') val (locul [ 'apropierea']);. $ ( '#' + Modelul + '- numele') val (locul [ 'nume']);. loadMap (locul [ 'geometrie'] [ 'locația'], locul [ 'name']);  

Aceasta umple toate câmpurile ascunse cu date de la Google și apeluri loadMap () pentru a afișa harta:

loadMap () funcția este foarte specifică pentru API Place Google și afișează harta pe care o vedeți mai sus la dreapta:

funcția loadMap (gps, nume) var gps_parse = gps.toString () înlocuiți ("(", ""); var gps_lat = parseFloat (gps_parse [0]); var gps_lng = parseFloat (gps_parse [1]); dacă document.querySelector ('articolul'). copii.length == 0) var mapcanvas = document.createElement ('div'); mapcanvas.id = 'mapcanvas'; mapcanvas.style.height = '300px'; mapcanvas.style.width = '300px'; mapcanvas.style.border = '1px solid negru'; document.querySelector ( 'articol') appendChild (mapcanvas).;  var latlng = nou google.maps.LatLng (gps_lat, gps_lng); // gps ['k'], gps ['D']); var myOptions = zoom: 16, centru: latlng, mapTypeControl: false, navigationControlOptions: stil: google.maps.NavigationControlStyle.SMALL, mapTypeId: google.maps.MapTypeId.ROADMAP; var hartă = nou google.maps.Map (document.getElementById ("mapcanvas"), myOptions); var marker = nou google.maps.Marker (position: latlng, map: map, title: name); 

Experiența utilizatorului este rapidă și impresionantă. Incearca-l!

Înregistrarea dinamică a schimbărilor de întâlnire

Apoi, să analizăm modul în care înregistrăm modificările planurilor de întâlnire în timp real. Nu există niciun API Google aici; este mai mult vanilla AJAX în cadrul Yii Framework.

Pe măsură ce utilizatorii adaugă date, ore și locuri în planurile lor de întâlnire, veți vedea o pagină ca aceasta:

Tu și Lor coloanele arată favorabilitatea fiecărui participant față de locurile și data. Mai mare Alege slider permite persoanei să ia decizia finală cu privire la locul și timpul întâlnirii.

Există o mulțime de date pe care trebuie să le colectăm de la oameni și nu vrem să cerem o reîmprospătare a paginii cu fiecare schimbare. Ajax este soluția ideală pentru această problemă.

Voi trece prin codul pentru panoul de întâlnire de mai sus. Panoul de întâlnire de mai sus funcționează în mod similar.

Urmărirea Codului

Din cauza cadrului MVC și a dorinței mele de a reutiliza partile de cod, fluxul de aici poate fi dificil de urmat. Funcțiile PHP helper și JavaScript, uneori, trebuiau să fie plasate în fișierele părinte, și nu pe cele paralele cu care au fost cele mai apropiate. Voi încerca să vă dau mai întâi o prezentare generală. Vă încurajez să faceți câteva treceri pe care le citiți pentru ao înțelege pe deplin. Și din nou, puteți naviga prin GitHub.

Sugestie: Țineți minte că numele de fișiere pentru paralele încep de obicei cu o subliniere.

  1. Pagina Planificatorului de întâlniri este încărcată la /frontend/views/meeting/view.php. Acest fișier conține, de asemenea, funcții JavaScript de ajutor pentru a gestiona starea butoanelor, cum ar fi Trimite și Definitivarea (adică după această modificare, utilizatorul poate trimite acum această invitație? Cu planificatorul de întâlniri, un loc și un moment trebuie selectați în general înainte de a putea fi trimis) și afișând notificări vizuale că modificările vor fi trimise prin e-mail altor participanți,.
  2. Când se afișează Unde panou pentru locații, se încarcă /frontend/views/meeting-place/_panel.php. Acest fișier include funcții PHP auxiliare showOwnerStatus () și showParticipantStatus (), care va fi refolosită de copilul său, _list.php. Dar, cel mai important, _panel.php include metode JavaScript pentru cursorul Bootstrap switchChange eveniment.
  3. Fișierul _panel.php utilizează _list.php pentru a afișa fiecare rând individual pentru fiecare loc. Acest fișier va afișa glisoarele Bootstrap apelând funcțiile _panel.php showOwnerStatus () și showParticipantStatus ().
  4. switchChange funcțiile vor face apelurile Ajax la MeetingPlaceChoiceController.php.
  5. În cele din urmă, MeetingPlaceChoiceController.php numește modelul MeetingPlaceChoice.php pentru a înregistra modificările din baza de date.

Îmi pare rău că plasarea codului relevant este complicată și răspândită. 

Acum vă voi îndruma pas cu pas prin componentele cheie.

Codul Ajax pas cu pas 

Iată reuniunea / view.php redarea Meeting-Place / _panel.php. Aceasta afișează parțial rândurile posibile și selecțiile participanților:

meeting_type == \ frontend \ models \ Meeting :: TYPE_PHONE || $ model / meeting-place / _panel ', [' model '=> $ model,' placeProvider '=> $ placeProvider, 'isOwner' => $ isOwner, 'viewer' => $ viewer,]); ?> 

Mai jos este JavaScript legat de acțiuni care răspund la rezultatele Ajax, dar nu sunt direct necesare pentru Ajax. Nu trebuie să înțelegeți ce înseamnă aceste funcții pentru a înțelege acest exemplu Ajax, dar le-am inclus, deoarece sunt chemați ca răspuns la evenimentele Ajax.

id, 'viewer_id': $ viewer, succes: funcția (data) if (data) $ ('# actionSend') removeClass ("dezactivat"); altceva $ ('# actionSend') addClass ("dezactivat"); return true; );  funcția refreshFinalize () $ .ajax (url: '$ urlPrefix / meeting / canfinalize', date: id: $ model-> id, 'viewer_id': $ viewer date) $ ('# actionFinalize') removeClass ("dezactivat") altceva $ ('# actionFinalize') addClass ("dezactivat");  JS; $ position = \ yii \ web \ Vizualizare :: POS_READY; $ this-> registerJs ($ script, pozitie $); ?>

Aici, în Meeting-Place / _panel.php, este creat tabelul cu locurile și selecțiile, invocând _list.php:

  $ placeProvider, 'itemOptions' => ['class' => 'item'], 'layout' => 'items', 'itemView' $ placeProvider-> count, 'isOwner' => $ isOwner, 'participant_choose_place' => $ model-> meetingSettings ['participant_choose_place']],])?> 
numără> 1 && ($ isOwner || $ model-> meetingSettings ['participant_choose_place'])) echo Yii :: t ('frontend', 'Alege'); ?>

Mai important, acesta include și JavaScript-ul de mai jos, pe care îl folosim pentru a face apeluri Ajax atunci când utilizatorul mută un comutator, schimbându-și starea. Funcțiile de selectare corespund glisorului de selecție albastră mai mare, în timp ce funcțiile de alegere corespund glisoarelor preferate.

$ script = <<< JS placeCount = $placeProvider->numara; // permite utilizatorului să seteze locul final $ ('input [name = "place-chooser"]) pe (' switchChange.bootstrapSwitch ', funcția (e, s) // console.log (e.target. (url: '$ urlPrefix / meeting-place / choose', date: id: $ model-> id, 'val': e. target.value, // e.target.value este selectat succesul modelului MeetingPlaceChoice: funcția (data) displayNotifier ('place'); refreshSend (); refreshFinalize (); // utilizatorii pot spune dacă un loc este o opțiune pentru aceștia $ ('input [name = "meeting-place-choice"]'). ("switchChange.bootstrapSwitch", funcția (e, s) // console. log (e.target.id, s); // true | false // set intval pentru a trece prin AJAX din starea booleană if (s) state = 1; altul state = 0; $ .ajax (url: 'urlPrefix / set-place-choice / set ', date: id: e.target.id,' state ': state, succes: function (data) displayNotifier (' place '); return true;);); JS; $ position = \ yii \ web \ Vizualizare :: POS_READY; $ this-> registerJs ($ script, pozitie $); ?>

Funcțiile de mai sus fac apelul la actionSet () în MeetingPlaceChoiceController pentru a răspunde la schimbarea comutatorului utilizând solicitările Ajax:

funcția publică funcțiaSet ($ id, $ state) Yii :: $ app-> răspuns-> format = \ yii \ web \ Răspuns :: FORMAT_JSON; // caution - probleme de tip AJAX primite cu val $ id = str_replace ('mpc -', ', $ id); // daca (Yii :: $ app-> user-> getId ()! = $ mpc-> user_id ) returnează false, dacă (intval ($ state) == 0 sau $ state == 'false') $ status = MeetingPlaceChoice :: STATUS_NO; altul $ status = MeetingPlaceChoice :: STATUS_YES; // $ mpc-> save (); MeetingPlaceChoice :: set ($ id, $ status, Yii :: $ app-> user-> getId ()); retur $ id;

Acțiunile controlerului care răspund prin Ajax trebuie să aibă un format de răspuns JSON (astfel Yii știe că nu sunt menite să furnizeze cod HTML):

Yii :: $ app-> răspuns-> format = \ yii \ web \ Răspuns :: FORMAT_JSON;

Iată-l MeetingPlaceChoice :: set () , care înregistrează acțiunile utilizatorului în baza de date și creează o intrare MeetingLog, care urmărește toate modificările în timpul planificării.

setul funcțiilor publice statice ($ id, $ status, $ user_id = 0, $ bulkMode = false) $ mpc = MeetingPlaceChoice :: findOne ($ id); dacă ($ mpc-> user_id == $ user_id) $ mpc-> status = $ status; $ Mpc-> Salvare (); dacă ($ $ bulkMode) // log numai atunci când nu este în modul vrac, adică acceptă toate // a se vedea setAll pentru mai multe detalii dacă ($ status == MeetingPlaceChoice :: STATUS_YES) $ command = MeetingLog :: ACTION_ACCEPT_PLACE;  altceva $ command = MeetingLog :: ACTION_REJECT_PLACE;  MeetingLog :: adăugați ($ mpc-> meetingPlace-> meeting_id, $ command, $ mpc-> user_id, $ mpc-> meeting_place_id);  return $ mpc-> id;  altfel return false; 

Caracteristici legate de schimbările întâlnirilor

În Planificatorul întâlnirilor, păstrez un jurnal al fiecărei modificări. Acest lucru îmi permite să știu când au trecut câteva minute de la ultima schimbare a unei persoane și să notifice ceilalți participanți la întâlnire. Este un experiment pe care îl încerc cu acest serviciu, în loc de a cere ca participanții să lovească trimiteți de fiecare dată când doresc să facă schimbări,. 

Cu toate acestea, acest lucru necesită instruirea acestora pentru a înțelege că este bine să le schimbați și să-l lăsați, adică să închideți fereastra browserului. Asa ca displayNotifier () funcțiile afișează câteva alerte bliț pentru a ajuta la acest lucru - în cele din urmă le voi lustrui în timp și le voi elimina pentru utilizatorii cu experiență.

De asemenea, MeetingLog îmi permite să generez un rezumat al textului istoricului de planificare al întâlnirii. Dacă sunteți interesat să aflați mai multe despre acest lucru, am scris despre asta în construirea sistemului de pornire: notificarea persoanelor despre schimbarea întâlnirilor și furnizarea notificărilor.

Ce urmeaza?

Sper că aceste exemple vă vor ajuta să înțelegeți principiile lui Ajax în Yii. Dacă sunteți interesat de Ajax mai avansat, intenționez să includ formularele încărcate de Ajax în seria Planificator de întâlniri. Și, desigur, Ajax este un domeniu în care comunitatea Yii nu a împărtășit multe exemple. În general, Ajax funcționează similar în Yii, așa cum se întâmplă în PHP și în alte cadre, astfel încât să puteți învăța din exemple din alte comunități-cadru.

Urmăriți tutorialele viitoare în programul nostru de programare cu seria Yii2 în timp ce continuăm să vă scufundăm în diferite aspecte ale cadrului. De asemenea, vă recomandăm să verificați seria noastră Building Your Startup With PHP, care utilizează șablonul avansat al lui Yii2, pe măsură ce construim o aplicație în lumea reală.

Dacă doriți să știți când vine următorul tutorial Yii2, urmați-mă @reifman pe Twitter sau verificați pagina de instructor. Pagina mea de instructor va include toate articolele din această serie de îndată ce vor fi publicate. 

Link-uri conexe

  • Ajax (Wikipedia)
  • Noțiuni de bază - Ajax (Mozilla Developers Network)
  • Yii2 Developer Exchange, site-ul meu de resurse Yii2
Cod