Bine ați venit în partea a treia a seriei noastre, care se concentrează pe construirea de aplicații utilizând Backbone. Dacă nu ați citit părțile unu și doi, vă recomand că vă recomandăm să faceți acest lucru - doar pentru a afla unde ne aflăm și ce am acoperit până acum.
În prima parte, am luat un aspect de bază și modele, opinii și colecții. În partea a doua, am analizat routerele, evenimentele și modulele de istorie. În această parte, vom examina mai departe interacțiunile și vom vedea cum putem adăuga sau elimina modele dintr-o colecție.
Dacă vă aduceți mintea înapoi în prima parte, vă veți aminti modul în care am adăugat toate modelele noastre colecției când a fost inițializată colecția. Dar cum putem adăuga modele individuale într-o colecție după ce colecția a fost deja inițializată? De fapt este foarte ușor.
Vom adăuga posibilitatea adăugării de contacte noi, care vor implica o actualizare a codului HTML și a vederii noastre principale. Mai întâi, codul HTML; adăugați următoarea notă la containerul de contacte:
Acest formular simplu va permite utilizatorilor să adauge un nou contact. Principalul punct este acela că id
attributess DIRECTIVEI elementele se potrivesc cu numele de atribute utilizate de modelele noastre, ceea ce face mai ușor obținerea datelor în formatul dorit.
Apoi, putem adăuga un manipulator de evenimente la vizualizarea noastră master, astfel încât datele din formular să poată fi recoltate; adăugați următorul cod după cheia existentă: pereche de valori din evenimente
obiect:
"faceți clic pe #add": "addContact"
Nu uitați să adăugați virgula din capăt la sfârșitul legării existente! De data aceasta specificăm clic
eveniment declanșat de element cu un id
de adăuga
, care este butonul din formularul nostru. Operatorul care ne obligă la acest eveniment este adaugă contact
, pe care îl putem adăuga în continuare. Adăugați următorul cod după filterByType ()
din partea a doua:
addContact: funcția (e) e.preventDefault (); var newModel = ; $ (el ()) (val)) == "()) newModel [el.id] = $ (" el) .val ();); contacts.push (formData); dacă (_.indexOf (this.getTypes (), formData.type) === -1) this.collection.add (contact nou (formData)); acest $ el.find ( "# filtru") găsește ( "selectați") șterge () de capăt () adăugați (this.createSelect ()).....; altceva this.collection.add (nou contact (formData));
Deoarece acesta este un handler de evenimente, acesta va primi automat eveniment
obiect, pe care îl putem folosi pentru a preveni comportamentul implicit al atunci când se face clic pe el (care ar fi să trimiteți formularul și să reîncărcați pagina - nu ceea ce dorim). Apoi vom crea un nou obiect gol și vom folosi jQuery
fiecare()
metodă pentru a itera pe fiecare element în nostru
adaugă contact
formă.
În funcția de apel invers furnizată la fiecare()
, verificăm mai întâi că câmpul a introdus text în ea și dacă da, adăugăm o proprietate nouă obiectului cu o cheie egală cu id
a elementului curent și o valoare egală cu curentul său valoare
. Dacă câmpul este gol, proprietatea nu va fi setată, iar noul model va moșteni toate valorile implicite care ar fi putut fi specificate.
Apoi, putem actualiza magazinul nostru local de date cu noul contact. Aici vom salva noile date pe server - dacă am avea un server disponibil pentru a primi astfel de cereri. În acest moment nu o facem, așa că vom actualiza acum matricea originală, astfel încât dacă vizualizarea este filtrată, noile date nu vor fi pierdute. Tot ce trebuie să facem este să folosim colecția adăuga()
de adăugare a datelor noi în colecție. Putem crea noul model pentru a trece în colecția din cadrul apelului către adăuga()
.
În cele din urmă, trebuie să actualizăm astfel încât dacă noul contact are un tip diferit, acel tip este disponibil pentru filtrare. Cu toate acestea, dorim doar să re-render
dacă a fost adăugat un nou tip. Putem folosi Underscore
Index de()
pentru a căuta printr-o matrice pentru o anumită valoare. Ca și JavaScript-ul nativ Index de()
metoda pentru siruri de caractere, aceasta metoda va reveni -1
dacă valoarea nu este găsită. Transmitem matricea pentru a căuta ca primul argument Index de()
, și valoarea de a căuta ca a doua.
Dacă valoarea nu a fost găsită, tipul specificat trebuie să fie nou, astfel încât să găsim caseta de selecție existentă și să o eliminăm înainte de a adăuga o nouă, generată de createSelect ()
metodă. În cazul în care tipul este găsit, putem adăuga noul model fără a fi nevoie să re-render selectați.
Acum, că am adăugat un nou model colecției, ar trebui să-l afișăm pe pagină. Pentru a face acest lucru putem lega un alt handler, de data aceasta pentru a asculta pentru adăuga
eveniment. Adăugați următoarea linie de cod la inițializa ()
metoda de colectare:
this.collection.on ("adăugați", acest.renderContact, acest lucru);
Noi folosim pe()
din nou, pentru a atașa ascultătorul evenimentului și întrucât deja avem o metodă care creează și afișează vizualizări individuale, specificăm doar acea funcție ca manipulant. De asemenea, setăm vizualizarea master ca acest obiect în cadrul procesorului, așa cum am procedat și cu cei care au efectuat operațiile anterioare. În acest moment, acum ar trebui să reușim să finalizăm formularul și să avem noul contact redat pe pagină:
Un lucru de remarcat este că dacă adaugă contact
câmpurile de formular sunt lăsate complet necompletate, modelul rezultat va fi aproape în întregime lipsit de atribute, ceea ce va cauza probleme atunci când încercăm să manipulăm modelul mai târziu. O modalitate de a evita acest lucru este de a furniza setări implicite pentru majoritatea atributelor modelului, la fel cum am furnizat implicit fotografie
atribut. Dacă nu există setări implicite pe care le putem folosi, ca și pentru numele unui contact, de exemplu, putem furniza un șir gol. Actualizați implicite
obiect în a lua legatura
clasa pentru a include valorile implicite pentru celelalte atribute ale noastre:
nume: "", adresa: "", tel: "", email: "", tip: ""
Acum, că știm cum să adăugăm modele la colecție, ar trebui să vedem cum pot fi eliminate și ele. O modalitate prin care putem permite ștergerea modelelor individuale este prin adăugarea unui buton de ștergere fiecărui contact, deci acesta este ceea ce vom face; mai întâi trebuie să actualizăm șablonul pentru fiecare vizualizare individuală astfel încât să conțină un buton de ștergere. Adăugați un nou buton la sfârșitul șablonului:
Asta e tot ce vom avea nevoie pentru acest exemplu. Logica pentru a elimina un model individual poate fi adăugată la clasa de vizualizare care reprezintă un contact individual, deoarece instanța de vizualizare va fi asociată cu o anumită instanță de model. Va trebui să adăugăm un eveniment obligatoriu și un manipulator de evenimente pentru a elimina modelul când se face clic pe buton; adăugați următorul cod la sfârșitul secțiunii ContactView
clasă:
evenimente: "click button.delete": "deleteContact", deleteContact: functie () var removedType = this.model.get ("type") laLowerCase (); this.model.destroy (); this.remove (); dacă (_.indexOf (director.getTypes (), removedType) === -1) directorul $ el.find ("# selectare filtru") copii ("[value = '" + removedType + ).elimina();
Noi folosim evenimente
obiect pentru a specifica obligativitatea evenimentului nostru, așa cum am făcut înainte cu viziunea noastră principală. De data aceasta ascultăm clic
evenimente declanșate de a care are numele clasei
șterge
. Handlerul obligat la acest eveniment este deleteContact
, pe care îl adăugăm după evenimente
obiect.
Mai întâi stocăm tipul de contact pe care tocmai l-am șters. Ar trebui să facem această valoare cu litere mici, așa cum am făcut înainte, pentru a ne asigura că nu există probleme de caz atunci când vizualizatorul de contacte este în uz.
Apoi chemăm distruge()
pe modelul asociat cu acest
, instanța de vedere. De asemenea, putem elimina reprezentarea HTML a vizualizării din pagină apelând jQuery elimina()
, care are bonusul suplimentar de a curăța orice manipulator de evenimente atașat la vedere.
În sfârșit, obținem toate tipurile de modele din colecția directoarelor și verificăm dacă tipul contactului care tocmai a fost eliminat este încă conținut în matricea rezultată. În caz contrar, nu mai există contacte de tipul respectiv și, prin urmare, ar trebui să eliminăm această opțiune din secțiunea selectare.
Selectăm elementul pe care trebuie să îl eliminăm întâi găsind caseta de selectare, apoi folosim un selector de atribute pentru a selecta cu un atribut de valoare care se potrivește cu
removedType
variabilă pe care am salvat-o la începutul metodei. Dacă eliminăm toate contactele unui anumit tip și apoi verificăm element, ar trebui să constatăm că tipul nu mai este în meniul drop-down:
Ok, această subpoziție este puțin înșelătoare; ceea ce vreau să spun este că, pe lângă eliminarea modelului și a vizualizării, ar trebui să eliminăm și datele originale din matricea de contacte pe care modelul a fost inițial construit. Dacă nu facem acest lucru, modelul care a fost eliminat va reveni ori de câte ori este filtrat. Într-o aplicație în lumea reală, probabil că vom sincroniza cu un sever pentru a persista datele.
Funcționalitatea de eliminare a elementului din matricea originală poate fi localizată în vizualizarea principală; colecția va declanșa a elimina
eveniment atunci când oricare dintre modele sunt eliminate din colecție, astfel încât să putem lega pur și simplu un handler pentru acest eveniment la colecția din vizualizarea master. Adăugați următoarea linie de cod direct după legările existente:
this.collection.on ("eliminați", this.removeContact, acest lucru);
Ar trebui să fiți destul de familiarizați cu această afirmație până acum, dar ca o reamintire, primul argument al pe()
metoda este evenimentul pe care îl ascultăm, cel de-al doilea este cel care execută atunci când apare evenimentul, iar cel de-al treilea este contextul pe care îl folosim ca acesta când executantul este executat. Înainte putem adăuga sterge contact()
metodă; după adaugă contact()
adăugați următorul cod:
removeContact: funcția (removeModel) var removed = removedModel.attributes; dacă (removed.photo === "/img/placeholder.png") delete deleted.photo; (contact, functie (contact) if (_.Equal (contact, eliminat)) contacts.splice (_ indexOf (contacte, contact), 1);
Backbone-ul trece cu ușurință handler-ul nostru modelul care tocmai a fost eliminat din colecție. Stocăm o referință la colecția de atribute, astfel încât să putem compara modelul care a fost eliminat cu elementele din matricea de contacte originale. Elementele originale din matricea de contacte nu au definit proprietatea fotografiei, dar deoarece aceasta este specificată ca o proprietate implicită, toate modelele noastre vor moșteni proprietatea și, prin urmare, vor eșua orice comparație cu obiectele din matricea de contacte.
În acest exemplu, trebuie să verificăm dacă fotografie
proprietatea modelului este aceeași cu valoarea implicită, iar dacă este, eliminăm fotografie
proprietate.
Odată ce acest lucru se face, putem itera peste fiecare element din contacte
și verificați-l pentru a vedea dacă este același cu modelul care a fost eliminat din colecție. Putem compara fiecare obiect cu obiectul pe care îl stocăm în variabila eliminată utilizând Underscore's este egal()
metodă.
În cazul în care este egal()
metoda returnează adevărat, apoi apelăm JavaScript-ul nativ lipitură()
metoda pe contacte
matrice, trecând în indexul elementului care urmează să fie eliminat și numărul de elemente de eliminat. Indicele este obținut utilizând Underscore's Index de()
metoda pe care am folosit-o mai devreme.
Acum, când se face clic pe un buton de ștergere, vizualizarea, modelul și datele originale vor fi șterse din existență. De asemenea, putem filtra afișarea, apoi revenim la vizualizarea tuturor contactelor, iar contactul care a fost eliminat nu va mai fi afișat.
Deci, am cam scos adaugă contact
formați pe pagină, nu-i așa? Pentru a închide această parte a tutorialului, putem face ceva pentru al păstra ascuns până când se face clic pe o legătură. Putem adăuga următorul link la element:
Adăugați un contact nou
Pentru ca linkul să afișeze formularul, va trebui să îl ascundem mai întâi și apoi să folosim un handler de evenimente UI pentru a-l arăta. Legarea poate fi adăugată la evenimente
obiect în DirectoryView
clasă:
"faceți clic pe #showForm": "showForm"
Al nostru showForm ()
metoda poate fi la fel de simplă, după cum urmează (deși probabil veți dori să faceți ceva mai mult cu ea decât noi!):
showForm: funcția () this. $ el.find ("# addContact") slideToggle ();
În acest tutorial, ne-am uitat doar la modul în care pot fi adăugate noi modele într-o colecție și modul în care modelele pot fi eliminate dintr-o colecție. Am văzut că metodele Backbone utilizate pentru a adăuga și a elimina modelele sunt, fără îndoială, adăuga()
și elimina()
metode.
De asemenea, am văzut cum putem lega persoanele care manipulează evenimentele care sunt declanșate automat atunci când aceste metode sunt folosite pentru a actualiza interfața de utilizare și colectarea după cum este necesar.
De asemenea, ne-am uitat la unele funcții utilitare Underscore mai utile pe care le putem folosi pentru a lucra cu datele noastre, inclusiv _Index de()
care returnează indexul unui element într-o matrice și este egal()
care pot fi folosite pentru a compara adânc două obiecte pentru a vedea dacă acestea sunt identice.
Ca și în ultima parte a acestui tutorial, am văzut și cum putem scrie clasele noastre în așa fel încât funcționalitatea lor să poată fi partajată și refolosită ori de câte ori este posibil. Atunci când am adăugat un nou model, de exemplu, am utilizat deja existența renderContact ()
metoda definită în DirectoryView
pentru a gestiona randarea codului HTML pentru noul contact.
Așadar, am văzut cum să adăugăm modele și să le eliminăm, să mă alăture în următoarea parte a acestei serii, unde vom analiza modul de editare a datelor existente ale modelului.