Construiți aplicații web utilizând Node.js

Introducere

În afară de API-urile de construire, Node.js este excelent pentru construirea de aplicații web standard. Dispune de instrumente puternice pentru a satisface gustul dezvoltatorilor web. În acest tutorial, veți construi o aplicație web care poate servi ca o bibliotecă locală. 

În timp ce construiți, veți afla despre unele tipuri de middleware, veți vedea cum să faceți față trimiterii formularului în Node.js și veți putea, de asemenea, să faceți referire la două modele.

Să începem.

Noțiuni de bază

Începeți prin instalarea generatorului expres pe mașina dvs..

npm instalează expres-generator -g

Rulați comanda generatorului de expresie pentru a genera aplicația.

exprima tutsplus-library -view = pug
 creați: tutsplus-library creați: tutsplus-library / package.json creați: tutsplus-library / app.js creați: tutsplus-library / public create: tutsplus-bibliotecă / rute / users.js creați: tutsplus-library / views creați: tutsplus-library / views / index.pug creați: tutsplus-library / views / layout.pug creați: tutsplus-library / views / : tutsplus-library / public / stylesheets creați: tutsplus-library / public / creați: tutsplus-library / public / stiluri / style.css dependente de instalare: $ cd tutsplus-library && npm install rulați aplicația: $ DEBUG = tutsplus-library: * npm start

Acum migrați în pachetul dvs. de lucru, deschideți pachetul.json și faceți dependențele similare cu cele de mai jos.

# pachetul.json "nume": "tutsplus-bibliotecă", "versiune": "0.0.0", "privat": true, "scripts" "dependență": "corp-parser": "~ 1.17.1", "connect-flash": "^ 0.1.1", "cookie-parser" 2.6.3 "," expres ":" ~ 4.15.2 "," mesaje exprese ":" ^ 1.0.1 "," sesiune expres ":" ^ 1.15.5 " 4.2.1 "," mongoose ":" ^ 4.11.12 "," morgan ":" ~ 1.8.1 "," pug ":" ~ 2.0.0-beta11 "," serv-favicon " 2 "

Rulați comanda pentru a instala pachetele.

npm install

Configurați fișierul de intrare

app.js a fost creată când ați rulat comanda generatorului; cu toate acestea, trebuie să configurați o configurație suplimentară. Editați fișierul pentru a arăta cum am mai jos.

# app.js var express = solicita ("expres"); var path = necesită ('path'); var favicon = necesită ("serv-favicon"); var logger = necesită ('morgan'); var cookieParser = necesită ('cookie-parser'); var bodyParser = necesită ('body-parser'); const constanta = necesita ('session-express') con const expresValidator = necesita ('express-validator') const const flash = “./routes/genres'); const cărți = cer ('./ rute / cărți'); var app = expres (); // 2 mongoose.Promise = global.Promise const mongoDB = process.env.MONGODB_URI || 'mongodb: //127.0.0.1/tutsplus-library' mongoose.connect (mongoDB) // vizualizați setarea motorului app.set ('views', path.join (__ dirname, 'views')); app.set ("motor de vizualizare", "pug"); // dezactivați după plasarea faviconului în / public //app.use (favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use (logger ( 'dev')); app.use (bodyParser.json ()); app.use (bodyParser.urlencoded (extended: false); app.use (cookieParser ()); app.use (expres.static (path.join (__ dirname, "public")); // 3 app.use (secret: secret: secret, resave: true) // 4 app.use (expressValidator) var namespace = param.split ('.'), root = namespace.shift (), formParam = root în timp ce (namespace.length) formParam + = ' msg: valoare, valoare)) // 5 aplicație (flash ()) aplicație (funcția (req, res, urm)) res.locals.messages = următor ()) // 6 app.use ('/ genres', genuri); app.use ('/ cărți', cărți); // captură 404 și transmitere către aplicația de gestionare a erorilor (funcția (req, res, urm)) var err = eroare nouă ("Nu a fost găsită"); err.status = 404; // error handler app.use (funcția (err, req, res, următorul) // setarea locală, furnizând numai eroare în dezvoltare res.locals.message = err.message; res.locals.error = req.app.get ('env') === 'dezvoltare'? err: ; // render pagina de eroare res.status (err.status || 500); res.render ('error');); module.exports = app;
  1. Ați cerut cele două rute pe care le veți folosi în construirea acestei aplicații. În curând veți crea fișierul de rute. Traseele necesare sunt atribuite ca valori pentru două variabile diferite care sunt utilizate la configurarea middleware-ului pentru rutele dvs..
  2. L-ai pus pe Mongoose să folosească global.Promise. Variabila MongoDB este atribuit MONGODB_URI din mediul dvs. sau pe calea spre serverul dvs. local mongo. Această variabilă este trecută ca argument pentru conectarea la serverul MongoDB care rulează.
  3. Ați setat mediul de sesiune utilizând Express-sesiune. Acest middleware este important deoarece veți afișa mesaje flash în anumite părți ale aplicației.
  4. Ați creat un middleware pentru validare. Acest middleware va fi folosit pentru a valida formularul de intrare, asigurându-se că utilizatorii aplicației nu trimit un formular gol. Validarea folosește un pachet instalat, Express-validator.
  5. Ați creat un middleware care va fi util la afișarea mesajelor flash. Acest middleware face uz de conectați-bliț.
  6. Rutele pentru aplicație sunt configurate pentru a utiliza fișierul de rute pe care l-ați solicitat. Solicitări care să indice /genuri și / cărți vor face uz de fișierele genurilor și cărților. În acest moment nu ați creat fișierele de rute, dar veți face acest lucru în curând.

Cartea și modelul de gen

Modelul de carte va face uz de Schema Mongoose pentru a defini modul în care vor fi structurate cărțile. Creați un director numit modele, și un nou fișier numit Book.js. Iată cum arată.

# modele / Book.js const mongoose = necesită ('mongoose') mongoose.Promise = global.Promise const Schema = mongoose.Schema const bookSchema = Schema (nume: string: un nume de carte ', descriere: tip: String, trim: true, autor: type: String, trim: true, gen: [genul: Schema.Types.ObjectId, ref:' Genre '] ) module.exports = mongoose.model ("Carte", bookSchema)

Aici aveți patru câmpuri. Ultimul câmp este utilizat pentru a stoca genul din care aparțin fiecare carte. Câmpul genului se referă aici la modelul Gen, care va fi creat în continuare. De aceea este setat tipul Schema.Types.ObjectId, unde se vor salva ID-urile fiecărui gen de referință. ref specifică modelul pe care îl referențiți. Rețineți că genul este salvat ca o matrice, ceea ce înseamnă că o carte poate avea mai mult de un gen.

Să mergem înainte să creați modelul Gen.

# modele / genre.js const mongoose = necesită ('mongoose') mongoose.Promise = global.Promise const Schema = mongoose.Schema const genreSchema = Schema (nume: type: String, trim: true, required un nume de gen ") module.exports = mongoose.model ('Genre', genreSchema)

Pentru genul tău, ai nevoie doar de un câmp: Nume.

Genul Index rute și vedere

Pentru acest tutorial, veți folosi două căi de traseu pentru genul dvs .: o cale de a adăuga genuri noi și o altă listă care conține listele despre genurile pe care le aveți. Creați un fișier din directorul dvs. de rute numit genres.js.

Începeți prin a solicita toate modulele pe care le veți folosi.

# trasee / genres.js var express = necesită ("expres"); var router = expres.Router (); const mongoose = necesită ('mongoose') const Genre = cer ('... / models / Genre')

Apoi, plasați ruta care gestionează fișierul index pentru genurile dvs..

(genre = res.render ("genuri", gen.reducere genuri: genuri, (err) => throw err));

Acest traseu este apelat ori de câte ori sunt făcute cereri /genuri. Aici numiți metoda de căutare din modelul genului pentru a obține toate genurile create. Aceste genuri sunt apoi redate pe un șablon numit genuri. Să mergem mai departe și să creăm asta, dar, mai întâi, actualizați-vă layout.pug pentru a arata astfel:

# views / layout.pug doctype html html titlu titlu = titlu link (rel = 'stylesheet', href = "/ stylesheets / style.css") link (rel = 'stylesheet', href = "https://bootswatch.com / script / src = 'https: // maxcdn .bootstrapcdn.com / bootstrap / 3.3.7 / js / bootstrap.min.js ') corpul .container-headerul blocului de lichid nav.navbar.navbar-inverse .container-fluid .navbar-header header.navbar-toggle.collapsed ( tip = 'buton', date-toggle = "restrângere", data-target = "# bs-example-navbar-collapse-2") span.sr -scrop span.icon-bar Span. icon-bar a.navbar-brand (href = '#') Bibliotecă locală # bs-example-navbar-colaps-2.collapse.navbar-collapse ul.nav.navbar-nav.navbar-right li a (href = / cărți ") Vizualizați cărți li a (href = '/ books / add') Adăugați New Book li a (href = '/ genres'

Acest lucru va oferi vederilor dvs. o structură frumoasă pentru a ajuta la navigație. Acum creați un fișier de vizualizare numit genre.pug. În acest fișier, veți trece prin genurile create și afișați fiecare gen într-o listă neordonată.

Iată cum ar trebui să arate fișierul.

# views / genres.pug extinde conținutul blocului de layout h1 genul ul.well.well-lg fiecare gen, i în genurile li.well.well-sm p # genre.name

Adăugați rute de gen și vederi noi

Întoarce-te la tine rute / genres.js pentru a adăuga rutele care vor gestiona crearea de noi genuri.

# rută / genres.js // 1 router.get ('/ add', (req, res, next) => res.render ('addGenre')) // 2 router.post (req, res, next) => req.checkBody ('nume', 'Numele este necesar'). ('addgenres', gen, erori) const genre = (gen nou (req.body)). ((erori) => console.log ('oops ...') console.log (erori))) // 3 module.exports = router;
  1. Funcția acestui router este să afișați pur și simplu pagina pentru adăugarea de noi rute. Acest router este sunat ori de câte ori sunt făcute cereri / genuri / add cale.
  2. Acest router se ocupă de depunerea formularului. Atunci când formularul este trimis, verificăm să se asigure că un nume este introdus de utilizator. Dacă nu este introdus niciun nume, pagina este re-redată. Dacă verificările sunt bune, genul este salvat și utilizatorul este redirecționat către /genuri pagină.
  3. Modulul este exportat ca un router.

Acum puteți continua și creați pagina pentru adăugarea unui gen nou.

# views / addGenre.pug extinde conținutul blocului de layout .row .col-md-12 h1 Adaugă formularul de carte (metoda = "POST", action = "/ genres / add") .form-group label.col-lg-2. control.label Numele .col-lg-10 input.form-control (tip = "text", nume = "nume") .form-group .col-lg-10.col-lg-offset-2 input.button. btn.btn-primary (type = 'submit', value = "Submit") dacă erori ul pentru eroare în eroare li! = error.msg

Cărți Trasee și Vizualizare

Creați un nou fișier de rutare pentru cărți și denumiți-l books.js. Așa cum ați făcut mai devreme cu genul, începeți prin a solicita modulele necesare.

# trasee / books.js var express = necesită ('express'); var router = expres.Router (); const mongoose = necesită ('mongoose') const Book = necesită ('... / models / Book') const Genre = necesită ('... / models / Genre')

Apoi, configurați routerul pentru a afișa toate cărțile salvate în bibliotecă. Încearcă-o singură în felul în care aranjezi genul; puteți verifica întotdeauna înapoi pentru a efectua corecții.

Cred că ai încercat asta, așa cum ar trebui să arate.

router.get ('/', (req, res, next) => const cărți = Book.find () cărți: cărți), (err) => throw err));

Când se solicită acest router, se face o solicitare de a găsi toate cărțile salvate în baza de date. Dacă totul merge bine, cărțile sunt afișate pe / cărți pagina, altfel o eroare este aruncată.

Trebuie să creați un fișier nou pentru afișarea tuturor cărților și, aici, ar trebui să arate cum ar trebui să arate.

# views / books.pug extinde conținutul blocului de layout h1 Cărți ul.well.well-lg fiecare carte, i în cărți li.well.well-sm a (href = '/ books / show / $ book.id') # book.name p = book.description

Pur și simplu treceți prin cărțile returnate și scoateți numele și descrierea fiecărei cărți folosind o listă neordonată. Numele cărții indică pagina individuală a cărții.

Adăugați noi rute de carte și vizualizare

Următorul ruter pe care l-ați configurat se va ocupa de adăugarea de cărți noi. Două rutere vor fi utilizate aici: una va face pur și simplu pagina, iar alta va face față trimiterii formularului.

Asa arata routerele.

router.get ('/ add', (req, res, next) => const genres = Genre.find ()  .catch ((err) => throw err)) router.post ('/ add', (req, res, next) => req.checkBody este necesar ') Notrempty () req.checkBody (' descriere ',' Descriere este obligatorie ') notEmpty () req.checkBody (' dacă (erori) console.log (erori) res.render ('addBooks', book, errors) const book = res.redirect ('/ cărți')) .catch ((erori) => console.log ('oops ...')))

În primul router, afișați / addBooks pagină. Acest router este apelat când se face o cerere /adăuga cale. Deoarece adăugarea de cărți ar trebui să aibă genuri, doriți să afișați genurile salvate în baza de date.

 const genres = genre.find (). exec () .then ((genuri) => 

Codul de mai sus găsește toate genurile din baza de date și le returnează în genurile variabile. Cu aceasta, veți putea să vă conectați prin genuri și să le afișați ca casete de selectare.

Al doilea router se ocupă de depunerea formularului. Mai întâi, verificați corpul cererii pentru a vă asigura că unele câmpuri nu sunt goale. Aici este locul unde Express-validator middleware pe care l-ați setat app.js vine la îndemână. Dacă există erori, pagina este re-redată. Dacă nu există nici una, noua instanță a cărții este salvată și utilizatorul este redirecționat către pagina / cărți.

Să mergem mai departe și să creăm vederile pentru asta.

Creați un nou fișier de vizualizare numit addBooks.pug. Rețineți că numele vizualizării corespunde primului parametru dat res.renderului. Acest lucru se datorează faptului că faceți un șablon. În timpul redirecționării, pur și simplu treceți calea pe care doriți să o redirecționați, așa cum ați făcut res.redirect ( '/' cărți).

După ce a stabilit acest lucru, trebuie să arătați cum ar trebui să pară punctele de vedere.

# views / addBooks.pug extinde conținutul blocului de layout .row .col-md-12 h1 Adaugă formularul de carte (metoda = "POST", action = "/ books / add") .form-group label.col-lg-2. control-label Nume .col-lg-10 input.form-control (type = "text", nume = "nume") .form-group label.col-lg-2.control-label Autor .col-lg-10 input.form-control (type = "text", nume = "autor") .form-group label.col-lg-2.control-label Descriere carte .col-lg-10 textarea # textArea.form-control = "3", nume = "descriere") .form-group label.col-lg-2.control-label Gen.col-lg-10 pentru genul în genuri .checkbox input.checkbox = genre, id genre._id, value = genre._id, checked = genre.checked) etichetă (pentru = genre._id) # genre.name .form-group .col-lg-10.col- lg-offset-2 input.button.btn.btn-primary (tip = 'trimite', value = "Trimite") dacă erori ul pentru eroare în eroare li! = error.msg 

Lucrul important pe care trebuie să-l observăm aici este forma acțiunii și a metodei. Când se face clic pe butonul de trimitere, faceți un a POST cererea de a / cărți / add. Un alt lucru - încă o dată, buclele prin colecția de genuri s-au întors și au afișat fiecare dintre ele.

Rezervați Show Route and View

Să abandonăm ruta pentru a face față solicitărilor făcute fiecărei pagini a cărților. În timp ce sunteți acolo, este important să vă exportați modulul.

# rută / books.js router.get ('/ show /: id', (req, res, următor) => const book = Book.findById (_id: req.params.id) .populate : 'genre', model: 'Genre', popula: path: 'genre', model: 'Book' ) .catch ((err) => throw err)) modul.exports = router;

Nici o magie nu se întâmplă aici.

În primul rând, cererile adresate acestui router trebuie să aibă un id: id-ul cărții. Acest id este obținut din paramațiile cererii folosind req.params.id. Acesta este folosit pentru a identifica cartea specifică care trebuie obținută din baza de date, deoarece ID-urile sunt unice. Când se găsește cartea, valoarea genului cărții este populată cu toate genurile care au fost salvate în acest exemplu de carte. Dacă totul merge bine, vizualizarea cărții este redată, altfel o eroare este aruncată.

Să creăm vederea pentru o carte. Iată cum ar trebui să arate.

blocul conținutului .well.well-lg h1 # [nume puternic:] # book.name ul li # [puternic Descriere:] # book.description li # [autor puternic]: # book.author [genul puternic:] fiecare gen din book.genre # genre.name |,

Puteți porni serverul de noduri prin executarea:

DEBUG = biblioteca tutsplus: * npm start

Concluzie

Acum știi cum să construiești o aplicație web standard în Node.js, nu doar o aplicație simplă de rezolvat. Ați putut să vă ocupați de depunerea formularului, de referință la două modele și să creați niște middleware.

Puteți merge mai departe prin extinderea aplicației - încercați să adăugați abilitatea de a șterge o carte. Mai întâi, adăugați un buton la pagina de prezentare, apoi accesați fișierele de rute și adăugați un router pentru aceasta. Rețineți că aceasta va fi a POST cerere.

De asemenea, vă puteți gândi la mai multe caracteristici pe care să le adăugați la aplicație. sper ca ti-a placut.

Cod