Folosind Prototype JavaScript cu MVC

În acest articol, vom examina procesul de utilizare a JavaScript, dintr-o perspectivă bazată pe MVC, pentru a manipula DOM. Mai precis, vom institui obiectele JavaScript, proprietățile și metodele lor, precum și instanțele lor paralele cu comportamentul dorit al viziunilor noastre (ceea ce vede utilizatorul).


Luați în considerare viziunile dvs. ca obiecte, nu ca pagini

În orice moment în dezvoltarea unei pagini web, folosim o limbă care promovează în mod natural fie dezvoltarea bazată pe clasă, fie dezvoltarea bazată pe obiecte. În limbile puternic tastate, cum ar fi Java și C #, scriem de obicei opiniile noastre în clase - oferindu-le stat, domeniu și context. Când lucrăm cu limbi precum PHP sau motoare de vizualizare mai noi, cum ar fi Razor pentru ASP.NET, punctele noastre de vedere pot fi pur și simplu marcare (HTML / CSS) amestecate cu templating. Cu toate acestea, aceasta nu înseamnă că trebuie să ne schimbăm percepția asupra modului în care părerea se comportă ca entitate proprie statală.

În Views, lucrăm în primul rând cu HTML, care constă din elemente imbricate; aceste elemente au atribute care descriu care este scopul lor semantic sau cum apar ele atunci când sunt redate. Aceste elemente au copii sau elemente părinte care mostenesc / furnizează comportamente în cascadă (prin CSS) și bloc / inline. Aceste elemente pot fi văzute în mod natural dintr-o perspectivă OOP (Object-Oriented Programming). Luați în considerare, de exemplu, următoarea marcare:

 div.container border: 1px solid # 333; padding: 5px; culoarea rosie; 
 

Despre compania noastră

Rezultat:

După cum puteți vedea mai sus, antetul a moștenit proprietatea de culoare a fonturilor din containerul părinte, prin comportamentul CSS al cascadării. Acest comportament este destul de similar cu conceptul de moștenire în OOP. De asemenea, vedem că antetul este un copil al containerului, moștenind anumite proprietăți, pe baza comportamentului elementului. Atunci când vedem elementele noastre din această perspectivă, avem o definiție mai bună a ceea ce intenționăm să facem cu elementele noastre de vedere și putem încadra mai bine stilurile și funcționalitatea.

Într-o vedere, vom avea marcaj. Cu toate acestea, acest marcaj poate avea imbinate vederi parțiale, cum ar fi barele laterale, un antet, un subsol, o șină dreapta (sau stânga) și una sau mai multe secțiuni de conținut. Toate aceste opinii parțiale ar trebui privite ca entitate proprie, capabile să aibă propria lor stare, context și domeniu de aplicare.

"Când vă concepeți vizualizările și vizualizările parțiale ca obiecte, aceasta face mult mai ușor de scris codul dvs. de pe partea clientului."


Traducerea acestui concept în stilurile și scripturile dvs.

Mulți dezvoltatori tind să scrie JavaScript din punct de vedere procedural sau funcțional și adesea neglijează să ia în considerare tendințele naturale oferite în abordările de dezvoltare bazate pe vizualizare și instanțierea paralelă (crearea unei noi instanțe a vizualizării pe măsură ce creăm o nouă instanță a unui JavaScript obiect care corespunde acestei viziuni) atunci când lucrează în cadrul MVC. Este adesea cazul în care mă întâlnesc în fișiere JavaScript care sunt doar o metodă după alta. Deși acest comportament funcționează și este obișnuit, nu este foarte eficient pentru întreținerea codului, depanarea sau extensia codului curent sau viitor când lucrați extensiv cu vizualizări.

Pentru a vă îndepărta de acest obicei și a începe să scrieți un cod de comportament mai bun, atunci când începeți să stabiliți scenariile și stilurile din View, urmați aceste reguli generale:

Reguli de aur pentru dezvoltarea JavaScript bazate pe vizualizare

  • Fiecare vizualizare care este redată dintr-o acțiune pe un controler ar trebui să aibă propriul obiect JavaScript.
  • Fiecare vizualizare parțială încărcată într-o vizualizare trebuie să aibă propriul obiect JavaScript.
  • Denumiți obiectele la fel ca vizualizările dvs. (sau vederi parțiale). Acest lucru va face mai mult sens pentru dvs. și toți ceilalți care vă ating codul.
  • Utilizați cazul Pascal pentru toate obiectele (adică Despre, Bara laterală etc.). Opiniile dvs. ar trebui deja, deci de ce nu faceți același lucru pentru obiectele JavaScript?
  • Toate constantele acestor obiecte ar trebui să fie stocate în constructor. Aceasta înseamnă că dacă vizualizarea dvs. are proprietăți care vor fi utilizate în mai multe metode, toate aceste metode pot accesa toate aceste proprietăți.
  • Toate metodele care vor fi chemați pe o vizualizare (sau o vedere parțială) ar trebui să fie legate de prototipul obiectului care corespunde acelei viziuni.
  • Toate legăturile de eveniment pentru vizualizare (sau vizualizare parțială) trebuie să fie conținute în metoda proprie de legare a evenimentului, care este plasată pe prototip.

Luați în considerare următoarea diagramă:

În general, creez script-uri și stiluri specifice vizualizării și apoi apuc ceea ce am nevoie de foile de stil principale și de bibliotecile de script create pe care le-aș folosi în multe vizualizări. Aceasta reduce, de asemenea, cantitatea de cod utilizat.


Crearea obiectelor bazate pe vizualizare

În acest articol, vom stabili structura paginii Despre noi pe un site bazat pe MVC. Pentru a începe, vom crea structura așa cum se arată mai sus în diagrama anterioară. De acolo, vom crea un obiect Despre și vom începe să adăugăm metode la prototip. Mai întâi, luați în considerare următorul aspect vizual:

Acesta este un aspect foarte logic și utilizat în mod obișnuit pentru o pagină Web. Ne putem segmenta pagina în obiecte vizuale separate. Pentru fiecare dintre aceste vederi, putem crea un obiect logic care să corespundă cu acesta. În general, omiteți informațiile repetitive din numele fișierului sau al clasei care este utilizat de MVC pentru a determina URI-ul de pe traseu și, în schimb, să rămânem cu ceva ușor de păstrat consecvent.

Pentru afișările de pagină, în general, denumesc obiectele mele JavaScript în numele vizualizării. Iată un exemplu de Obiectul meu DespreViz:

 // Vizualizați numele fișierului: AboutView.cs (.NET MVC 1.0), About.cshtml (.NET MVC 3.0) sau AboutView.php (PHP) var Despre = funcția (pageTitle) this.pageTitle = pageTitle; // legarea evenimentelor de îndată ce obiectul este instanțiat this.bindEvents (); ;

În exemplul de mai sus, am creat un obiect JavaScript în formatul funcției, oferindu-i capacitatea de a servi ca constructor de obiecte pentru toate metodele numite pentru vizualizarea aproximativă. Prin alegerea acestui format, putem instanțializa o nouă instanță acest, la fel cum facem și cu vizualizarea Server-Side (spunând new AboutView ();). De aici, putem atribui proprietăți și metode acestui obiect. Pentru a atribui metode acestui obiect, vom avea nevoie de acces la prototipul obiectului.


Prototype-ul JavaScript este prietenul tău

Dezvoltatorii sunt deseori atenuați de evazivitatea (și ambiguitatea) obiectului prototip JavaScript.

Dezvoltatorii sunt deseori atenuați de evazivitatea (și ambiguitatea) obiectului prototip JavaScript. Pentru mulți, poate fi confuz să folosiți și să înțelegeți și să adăugați o altă dimensiune la codificare. Pe măsură ce JavaScript devine mai accentuat de evenimente cu concepte HTML5, AJAX și web 2.0, JavaScript tinde să se aplece în mod natural la dezvoltarea procedurală ușor dezvoltată, dar greu de întreținut, scalabilă și replicată.

Gândește-te la cuvânt Prototip ca un nume de gresit pentru moment. Când mă gândesc Prototip, Mă gândesc la un "proiect brut" sau la o bază pentru moștenire, dar acest lucru nu este exact cazul.

"În realitate, perspectiva mai bună pentru Prototype ar fi Pointerul Obiectului în memorie".

Atunci când creăm un obiect, instanțiăm apoi o nouă instanță a acestuia. Când facem acest lucru, vom crea un loc în memorie că obiectul poate fi referit (amintiți-vă, Obiecte în JavaScript sunt tipuri de referință, nu tipuri primitive; creând o altă variabilă egală cu acel obiect și apoi schimbarea valorilor sale va schimba de fapt obiectul original în pointer). Atunci când creați un obiect, instanțiați o nouă instanță a acestuia și apoi modificați "Pointer" sau Prototip, adăugăm direct câmpuri și metode la acel obiect în memorie (evident, dorim să adăugăm toate aceste lucruri înainte de instanțiere).

Iată un exemplu de creare de metode pe Despre obiect prototip:

 var Despre = funcție (pageTitle) this.pageTitle = pageTitle; // legarea evenimentelor de îndată ce obiectul este instanțiat this.bindEvents (); ; var Despre About.prototype.bindEvents = function () // Context curent: 'this' este obiectul About // Introduceti toate legaturile evenimentului intr-un singur loc si apelati-le // in propriile lor metode dupa cum este necesar. $ ('ul.menu') pe ('click', 'li.search', $ .proxy (this.toggleSearch, this)); ; var About.prototype.toggleSearch = funcția (e) // Comutați caracteristica de căutare pe pagină;

După cum puteți vedea mai sus, am conținut proprietățile obiectului About în cadrul constructorului, am creat un singur punct de referință pentru evenimentele obligatorii (în acest caz, folosim jQuery pentru a crea legăturile evenimentului, dar puteți utiliza orice cadru sau JavaScript în sine) și am plasat metoda toggleSearch pe prototipul obiectului About pentru a conține acea metodă pentru obiectul respectiv. De asemenea, am sunat bindEvents () metoda în obiect astfel încât să fie apelată la instanțiere.

Acum, ia în considerare următorul cod pentru Vizualizarea parțială a barei laterale:

 var pSidebar = funcție (pageTitle) this.pageTitle = titlul paginii; // apelați metoda bindEvents la instanțierea obiectului pSidebar. // aceasta va lega evenimentele obiectului this.bindEvents (); ; var pSidebar.prototype.bindEvents = functie () // context actual: 'this' este obiectul sidebar $ ('ul.menu') on ('click', 'li.has-submeniu', $ .proxy this.toggleSubMenu, aceasta)); $ ('input # search') pe ('click', $ .proxy (this.openSearch, this)); ; var pSidebar.prototype.toggleSubMenu = funcția (e) // comutarea submeniului // contextul curent: 'this' este pSidebar obj;

NOTĂ: Am chemat obiectul pSidebar pentru că este vorba despre a vedere parțială, nu o vizualizare completă. Aceasta este preferința mea de a distinge între cele două, dar face lucrurile mai clare.

Frumusețea utilizării acestei abordări este - putem folosi aceleași nume pe care le-am folosit în obiectul Despre și nu vom avea conflicte. Acest lucru se datorează faptului că aceste metode sunt legate de obiect prototip ea însăși, nu spațiul de nume global. Acest lucru simplifică codul nostru și permite un fel de "template" pentru scenariile viitoare.


Instanțiate numai după cum este necesar

Odată ce ați creat obiectele, numirea acestora este simplă. Nu mai trebuie să depindeți de cadrele dvs. pentru a declanșa evenimente când documentul este încărcat sau pregătit. Acum, puteți să vă instanțiați pur și simplu obiectul și evenimentele sale vor fi legate și executate după cum este necesar. Deci, haideți să ne instanțiăm Despre obiect:

În interiorul vizualizării în care ați numi scripturile specifice vizualizării (în funcție de limbajul dvs. de template), pur și simplu apelați o nouă instanță a obiectului și includeți fișierul după cum urmează:

  

După cum puteți vedea, am trecut în titlul paginii pentru vizualizare (care poate fi orice argument pentru orice nevoie - chiar Date model. Acest lucru vă oferă un context excelent asupra datelor dvs. de model și vă permite să manipulați cu ușurință acele date în JavaScript.

La fel ca al tău Despre Obiect, sunând la opiniile dvs. parțiale este la fel de ușor. V-aș recomanda să solicitați noi instanțe ale vizualizării parțiale a obiectelor JavaScript în cadrul constructorului obiectului - aceasta vă asigură că numiți numai acestea după cum este necesar și că sunt colectiv într-un singur loc.

 var Despre = funcție (pageTitle) this.pageTitle = pageTitle; // atribuirea unei noi instanțe din Vizualizarea parțială a barei laterale care va fi menționată mai târziu this.sidebar = noua pSidebar (pageTitle); // NOTĂ: Dacă nu aveți nevoie să faceți referire la o vizualizare parțială după fapt, // puteți să instanțiați o instanță a acesteia fără a o atribui în cadrul constructorului obiectului, astfel: new pSidebar (pageTitle); // face același lucru pentru subsolul parțial Vezi acest.footer = nou pFooter (); // legarea evenimentelor de îndată ce obiectul este instanțiat this.bindEvents (); ;

După cum puteți vedea, prin referirea obiectului Barei laterale ca o proprietate locală a obiectului Despre, acum legăm instanța, care este un comportament foarte natural - această instanță este acum bara laterală a paginii Despre pagină.

Dacă nu aveți nevoie să faceți referire la o vizualizare parțială după fapt, puteți să instanțiați o instanță a acesteia fără a o atribui în cadrul constructorului obiectului, astfel:

 var Despre = funcție (pageTitle) this.pageTitle = pageTitle; nou pSidebar (paginaTitlu); // legarea evenimentelor de îndată ce obiectul este instanțiat this.bindEvents (); ;

De aici, tot ce trebuie să facem este să adăugăm un alt script la scenariile noastre numite în opinia noastră:

   

De ce această tehnică este benefică

Odată ce această structură este instalată, putem să adaptăm obiectul nostru JavaScript pentru a se potrivi cu viziunea noastră și să aplicăm metodele necesare acelui obiect pentru a menține domeniul de aplicare. Prin crearea unui obiect paralel cu vizualizarea și prelucrarea prototipului acestui obiect, vom vedea următoarele avantaje:

  1. Nomenclatorul facilitează navigarea prin cod
  2. În mod natural, domeniul nostru numește obiectele, reducând necesitatea unor nume de metode lungi și utilizarea prea mare a închiderii anonime.
  3. Puțin până la nici un conflict în alt cod, deoarece metodele noastre sunt pe prototipul obiectului, și nu pe plan mondial
  4. Atunci când instanțiăm părerile noastre parțiale în cadrul constructorului de obiecte al lui View și le atribuim unei referințe de variabile locale, creăm în mod efectiv o copie legată local a obiectului Parțial vizual.
  5. Avem o definiție fermă a contextului și suntem capabili să folosim cuvântul cheie "acest" fără să vă faceți griji.
  6. Debugarea devine clară deoarece toate metodele afișate în stivă sunt legate într-un singur loc.

Concluzie

Deoarece modelul de design MVC continuă să devină mai popular în lumea designului, dezvoltarea obiectelor JavaScript care să însoțească manipularea DOM Element se va schimba pentru a fi mai adaptată la manipularea specifică vizuală și evenimentului. Prin adaptarea obiectelor JavaScript pentru a crea instanțe în paralel cu viziunile noastre, putem avea o relație statală în mână între cei doi - unul care este gustat în mod sâmbătă, ușor de trecut, ușor de întreținut și perfect pentru expansiune vizualizarea crește sau se modifică, creând o relație permeabilă și extensibilă între markup și scripting.

Prin utilizarea prototipului Obiectului, putem să menținem un context precis în obiectul de scripting al lui View și să extindem acel obiect cu un cadru de dezvoltare cu repetiție. Putem reproduce apoi acest format prin opiniile noastre parțiale, economisind timpul, puterea creierului și riscul de bug-uri și comportament neașteptat.

Cod