Aplikacja (księgarnia) działa w dwóch trybach: „strona główna” (Rysunek 6.1) oraz „gatunek” (Rysunek 6.2). W trybie gatunek część adresu, mianowicie, path
, jest nazwą gatunku.
Aplikacja została zaimplementowana w oparciu o moduł express
oraz maszynę szablonów ejs
. Nie jest to jedyny sposób na tworzenie aplikacji internetowej w node.js
Struktura plików aplikacji podana jest na poniższym obrazku.
. ├── db │ └── books.js ├── Gruntfile.js ├── package.json ├── public │ ├── css │ │ └── styl.css │ └── favicon.ico ├── serwer.js └── views ├── index.ejs └── partials ├── footer.ejs ├── genre.ejs ├── header.ejs ├── main.ejs ├── nav_genres.ejs └── ul_genres.ejs
Na najwyższym poziomie znajdują się trzy pliki:
Gruntfile.js
W tym pliku określa się zadanie dla grunta. W szczególności, jakie pliki trzeba zarchiwizować do pliku zurek.zip
.
package.js
W tym pliku określa się konfiguracja projektu. W szczególności, jakie moduły powinny zostać zainstalowane poleceniem npm install.
serwer.js
W tym pliku jest właściwie aplikacja serwerowa.
Pozostałe pliki umieszczone są w katalogach:
db
Tu znajduje się plik z bazą danych. Obsługa bazy danych została zaimplementowana za pomocą modułu taffy
.
public
W tym katalogu są pliki, które zostaną wysłane do klienta bez zmian. Na przykład, plik styl.css
.
views
W tym katalogu znajdują się szablony ejs. Szablony te zawierają znaczniki HTML oraz specjalne znaczniki, w których są zawarte wyrażenia w JavaScript, które zostaną obliczane podczas serwowania strony. Wartości zmiennych dla szablonu obliczane są w serwer.js
. Szablon główny, index.ejs
, został podzielony na części składowe, które są umieszczone w katalogu views/partials
Na początku ładuje się moduły. Co robi moduł morgan? Zwróć uwagę, że moduł ./db/books
z bazą danych nie jest standardowym. Zajrzyj do jego kodu.
/*jshint globalstrict: true, devel: true, node: true */ 'use strict'; let express = require('express'); let app = express(); let path = require('path'); let bodyParser = require('body-parser'); let favicon = require('serve-favicon'); let morgan = require('morgan'); let baza = require('./db/books');
Ustawia się ejs jako maszynę szablonów
app.set('view engine', 'ejs');
Rejestruje się moduły do wykorzystania z expresem.
app.use(morgan('dev')); app.use(favicon(__dirname + '/public/favicon.ico')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(express.static(path.join(__dirname, 'public')));
Rejestracja callbacków dla generowania odpowiedzi na żądania klienta. W trybie „strona główna” żądanie przychodzi metodą get
na /
. W trybie „gatunek” żądanie przychodzi metodą get
na /:genre
, przy czym genre
staje się zmienna (zwróć uwagę na dwukropek). Metodą post
przychodzą dane z formularza. Czemu tak się dzieję? Czy widzisz, w jaki sposób przekazywane są dane do szablonu?
app.get('/', function (req, res) { let genres = baza().distinct("genre"); res.render('index.ejs', {genres: genres}); }); app.get('/:gen', function (req, res) { let genres = baza().distinct("genre"); let books = baza({genre: req.params.gen}).select("title", "author"); let genre = req.params.gen; res.render('index.ejs', {genres: genres, books: books, genre: genre}); }); app.post('/:gen', function (req, res) { let newAuthor=req.body.author; let newTitle=req.body.title; let genre = req.params.gen; console.log(newAuthor, newTitle); let genres = baza().distinct("genre"); let books = baza({genre: genre}).select("title", "author"); res.render('index.ejs', {genres: genres, books: books, genre: genre}); });
Uruchamia się serwer na porcie 3000.
app.listen(3000, function () {
console.log('Serwer działa na porcie 3000');
});
Opracowanie zdarzenia SIGINT
(CTRL+C na serwerze).
process.on('SIGINT',function(){ console.log('\nshutting down'); process.exit(); });
<%- include("partials/header.ejs") %> <% if( typeof books == 'undefined') { %> <%- include("partials/main.ejs")%> <% } else {%> <%- include("partials/genre.ejs")%> <% } %> <%- include("partials/header.ejs") %>
We wszystkich szablonach tryby pracy aplikacji rozróżniane są tak: w trybie „strona główna” zmienna books
nie jest określona.