Buchlisten-Seite
Als Nächstes implementieren wir unsere Buchlisten-Seite. Diese Seite soll eine Liste aller Bücher in der Datenbank zusammen mit ihrem Autor anzeigen, wobei jeder Buchtitel ein Hyperlink zur zugehörigen Buchdetailseite ist.
Controller
Die Controller-Funktion für die Buchliste muss eine Liste aller Book
-Objekte in der Datenbank abrufen, diese sortieren und dann an die Vorlage zur Darstellung übergeben.
Öffnen Sie /controllers/bookController.js. Finden Sie die exportierte book_list()
-Controller-Methode und ersetzen Sie sie durch den folgenden Code.
// Display list of all books.
exports.book_list = asyncHandler(async (req, res, next) => {
const allBooks = await Book.find({}, "title author")
.sort({ title: 1 })
.populate("author")
.exec();
res.render("book_list", { title: "Book List", book_list: allBooks });
});
Der Routen-Handler ruft die find()
-Funktion auf dem Book
-Modell auf, um nur title
und author
zurückzugeben, da wir die anderen Felder nicht benötigen (es werden auch die Felder _id
und virtuelle Felder zurückgegeben), und sortiert die Ergebnisse alphabetisch nach dem Titel mit der sort()
-Methode. Wir rufen auch populate()
auf Book
auf und spezifizieren das author
-Feld—dies wird die gespeicherte Buchautoren-ID durch die vollständigen Autorendetails ersetzen.
exec()
wird dann angehängt, um die Abfrage auszuführen und ein Versprechen zurückzugeben.
Der Routen-Handler verwendet await
, um auf das Versprechen zu warten, und pausiert die Ausführung, bis es erfüllt wird. Wenn das Versprechen erfüllt ist, werden die Ergebnisse der Abfrage in der Variablen allBooks
gespeichert und der Handler setzt die Ausführung fort.
Der letzte Teil des Routen-Handlers ruft render()
auf, spezifiziert die book_list (.pug) Vorlage und übergibt Werte für title
und book_list
in die Vorlage.
Ansicht
Erstellen Sie /views/book_list.pug und kopieren Sie den folgenden Text hinein.
extends layout
block content
h1= title
if book_list.length
ul
each book in book_list
li
a(href=book.url) #{book.title}
| (#{book.author.name})
else
p There are no books.
Die Ansicht erweitert die layout.pug-Basisvorlage und überschreibt den block
namens 'content'. Sie zeigt den title
an, den wir vom Controller über die render()
-Methode übergeben haben, und durchläuft die book_list
-Variable mit der each
-in
-Syntax. Ein Listenelement wird für jedes Buch erstellt, das den Buchtitel als Link zur Buchdetailseite anzeigt, gefolgt vom Autorennamen. Falls keine Bücher in der book_list
vorhanden sind, wird der else
-Abschnitt ausgeführt und zeigt den Text 'Es gibt keine Bücher' an.
Hinweis:
Wir verwenden book.url
, um den Link zum Detaildatensatz für jedes Buch bereitzustellen (wir haben diese Route implementiert, aber die Seite noch nicht). Dies ist eine virtuelle Eigenschaft des Book
-Modells, die das _id
-Feld der Modellinstanz verwendet, um einen eindeutigen URL-Pfad zu erzeugen.
Interessant ist hier, dass jedes Buch als zwei Zeilen definiert ist, wobei für die zweite Zeile die Pipe verwendet wird. Diese Vorgehensweise ist notwendig, weil der Autorenname Teil des Hyperlinks wäre, wenn er in der vorherigen Zeile stünde.
Wie sieht das aus?
Führen Sie die Anwendung aus (siehe Testen der Routen für die relevanten Befehle) und öffnen Sie Ihren Browser unter http://localhost:3000/
. Wählen Sie dann den Alle Bücher-Link aus. Wenn alles korrekt eingerichtet ist, sollte Ihre Seite etwa wie der folgende Screenshot aussehen.
Nächste Schritte
- Zurück zu Express Tutorial Teil 5: Anzeige von Bibliotheksdaten.
- Fahren Sie fort mit dem nächsten Unterartikel von Teil 5: BookInstance-Listen-Seite.