Let Mavo Shine in Building Interactive Web Applications

Avatar of Dmitry Sharabin
Dmitry Sharabin on

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wie Sie sich am Titel denken könnten, ist dieses Tutorial Mavo gewidmet: eine neue, zugängliche Methode, um komplexe, reaktive, persistente Webanwendungen zu erstellen, indem man einfach HTML und CSS schreibt, ohne eine einzige Zeile JavaScript und kein Server-Backend.

Die App, die wir gemeinsam bauen werden, ist eine Karteikarten-Lern-App für Sprachlerner. Es ist eine voll funktionsfähige CRUD-Anwendung, die es Ihnen ermöglicht,

  • Karteikarten zu erstellen, zu löschen, zu aktualisieren und sie per Drag and Drop neu anzuordnen.
  • Karteikarten zu importieren und zu exportieren.
  • Zu bewerten, wie gut Sie das Wort auf einer Karteikarte gelernt haben.

So sieht unsere fertige Anwendung aus

Im Tutorial werde ich Sie durch den gesamten Prozess der Erstellung der App führen.

Am Ende einiger Schritte gebe ich Ihnen Vorschläge, mit Mavo zu experimentieren – um etwas mehr zu lernen – und einige Verbesserungen an der Anwendung vorzunehmen, die wir gerade erstellen.

Sind Sie bereit? Los geht's! 😀

Statisches Template

See the Pen
01. Statisches Template
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Um zu veranschaulichen, wie Mavo Standard-HTML verbessert, werden wir zuerst eine rein statische HTML-Seite erstellen und dann Mavo verwenden, um dieses statische HTML in eine voll funktionsfähige Webanwendung zu verwandeln.

Nehmen wir an, wir haben den folgenden HTML-Code innerhalb von <body>

<header>
  <h1>Flashcards</h1>
</header>

<main>
<article>
  <p>Word or phrase</p>
  <p>Translation</p>
</article>
</main>

In diesem Code repräsentiert das <article>-Element eine einzelne Karteikarte.

Fügen wir etwas Styling hinzu, um unser HTML eher wie eine tatsächliche Karteikarten-App aussehen zu lassen. Sie können sich den Quellcode ansehen und damit spielen hier.

Erste Schritte mit Mavo

Im Moment haben wir nur ein statisches Template. Es ist Zeit, Funktionalität hinzuzufügen, damit es tatsächlich wie eine Karteikarten-Anwendung funktioniert. Hier kommt Mavo!

Um Mavo zu verwenden, müssen wir zuerst seine JavaScript- und CSS-Dateien in den <head>-Bereich unserer Seite einbinden

<head>
  ...
  <script src="https://get.mavo.io/mavo.min.js"></script>
  <link rel="stylesheet" href="https://get.mavo.io/mavo.css">
  ...
</head>

Definieren einer Mavo-App

Um Mavo-Funktionalität auf einer HTML-Struktur zu aktivieren, müssen wir das Attribut mv-app auf dem Element verwenden, das unsere Mavo-App enthält (das kann sogar das <body>- oder <html>-Element sein, das ist in Ordnung!). Sein Wert ist eine ID für unsere App, die auf der Seite eindeutig sein sollte.

In Anbetracht dessen, dass das <main>-Element unsere Mavo-App darstellt, fügen wir ihm das Attribut mv-app hinzu und geben unserer App die ID "flashcards"

<main mv-app="flashcards">
  ...
</main>

Das property-Attribut

See the Pen
02. Das property-Attribut
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Es ist an der Zeit, Mavo mitzuteilen, welche Elemente unserer App *wichtig* sind, d. h. welche Elemente wir bearbeitbar und speicherbar machen wollen.

Jetzt haben wir zwei solcher Elemente, und das sind die <p>-Elemente. Fügen wir diesen Elementen das Attribut property hinzu, um Mavo mitzuteilen, dass sie Daten enthalten. Elemente mit dem Attribut property werden als Properties bezeichnet.

Denken Sie daran, dass der Wert des Attributs property das Element beschreiben sollte, ähnlich wie ein id- oder class-Attribut

...

  <p property="source">Word or phrase</p>
  <p property="translation">Translation</p>

...

Haben Sie Änderungen an unserer App bemerkt? Die Mavo-Toolbar mit einer Schaltfläche Edit ist oben auf der Seite erschienen. Die Schaltfläche Edit ermöglicht es dem Benutzer, zwischen Lese- und Bearbeitungsmodus umzuschalten. Jetzt ist unsere App im Lesemodus. Das bedeutet, wir können die Daten auf der Seite nicht bearbeiten.

Wechseln wir nun in den Bearbeitungsmodus, indem wir auf die Schaltfläche Edit klicken. Was hat sich geändert? Der Text der Schaltfläche Edit wird zu Editing, um anzuzeigen, dass wir uns im Bearbeitungsmodus befinden. Wenn Sie mit der Maus über die Absätze fahren, teilt Mavo Ihnen durch gelbe Hervorhebung mit, dass Sie sie bearbeiten können. Machen Sie es! Klicken Sie auf den Text und bearbeiten Sie ihn. Wow! Wir können den Inhalt der Seite direkt vor Ort ändern!

💻 Lasst uns die Hände schmutzig machen!

Nehmen wir an, dass die Karteikarte neben dem Wort und seiner Übersetzung auch ein Beispiel für die Verwendung des Wortes in einem Satz enthalten soll. Erweitern Sie die App, indem Sie die entsprechenden Elemente zur Karteikarte hinzufügen.

Das mv-multiple-Attribut

See the Pen
03. Das mv-multiple-Attribut
by Dmitry Sharabin (@dsharabin)
auf CodePen.

An diesem Punkt haben wir nur eine Karteikarte in unserer App. Das ist nicht sehr nützlich! Für eine funktionierende Karteikarten-Anwendung benötigen wir die Möglichkeit, Karteikarten hinzuzufügen, zu löschen und neu anzuordnen. Wie können wir das tun? Wir *könnten* mehr Karteikarten erstellen, indem wir mehr <article>-Elemente zu unserem Code hinzufügen, aber wie erstellt und löscht ein Endbenutzer dann Karteikarten?

Glücklicherweise hat Mavo etwas zu bieten, das dies zum Kinderspiel macht: das Attribut mv-multiple, das Mavo mitteilt, dass bestimmte Elemente *multipliziert* werden können. Es wandelt das Element, auf dem es verwendet wird, in eine bearbeitbare Sammlung von Elementen um und generiert (anpassbare) Benutzeroberflächen zum Hinzufügen, Löschen und Neuordnen von Elementen.

Verwenden wir das Attribut mv-multiple in unserer App, um unsere einsame Karteikarte in eine Sammlung von Karteikarten umzuwandeln

<article property="flashcard" mv-multiple>
  ...    
</article>

Schalten Sie nun die App in den Bearbeitungsmodus. Beachten Sie, dass unter der Karteikarte jetzt eine Schaltfläche Add flashcard vorhanden ist. Probieren wir es aus: Erstellen Sie einige Karteikarten mit Hilfe dieser Schaltfläche. Jetzt können wir dynamisch neue Elemente direkt in der App hinzufügen, obwohl keine entsprechenden Elemente im HTML vorhanden sind. Aber das ist noch nicht alles!

Fahren Sie mit der Maus über eine Karteikarte und bemerken Sie die drei Schaltflächen, die in der oberen rechten Ecke erscheinen, zum *Hinzufügen*, *Löschen* und *Neuordnen* von Elementen über einen Drag-and-Drop-Griff. Und wenn Sie über eine beliebige Elementleistenschaltfläche fahren, können wir verstehen, zu welcher Karteikarte sie gehört: Mavo hebt sie hervor. Ist das nicht erstaunlich?

Das mv-storage-Attribut

See the Pen
04. Das mv-storage-Attribut
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Jetzt, da die grundlegende UI vorhanden ist, versuchen wir Folgendes

  • Wechseln Sie in den Bearbeitungsmodus (falls noch nicht geschehen).
  • Bearbeiten Sie das Quellwort und die Übersetzung der ersten Karteikarte. Fügen Sie auch ein paar weitere Karteikarten hinzu.
  • Schalten Sie die App zurück in den Lesemodus.
  • Und schließlich… aktualisieren Sie die Seite.

Was?! Wo sind unsere Daten geblieben? Sollte Mavo sie nicht speichern? Was ist passiert?

Tatsächlich haben wir Mavo nie mitgeteilt, *ob* oder *wo* unsere Daten gespeichert werden sollen!

Dazu müssen wir das Attribut mv-storage verwenden. Welche Optionen haben wir? Nun, Mavo eröffnet uns großartige Möglichkeiten, und Mavo-Plugins eröffnen noch mehr!

In unserer Anwendung werden wir die Daten im localStorage des Browsers speichern, was eine der einfachsten verfügbaren Optionen ist und sich daher gut für unsere erste Mavo-App eignet. Wir müssen nur das Attribut mv-storage mit dem Wert local zu dem Element mit dem Attribut mv-app (auch *Mavo-Root* genannt) hinzufügen.

<main mv-app="flashcards" mv-storage="local">
  ...
</main>

Schauen Sie sich die Mavo-Toolbar an. Haben Sie etwas bemerkt? Eine weitere Schaltfläche ist erschienen – die Schaltfläche Save.

Versuchen Sie, die App-Daten noch einmal zu bearbeiten. Beachten Sie, dass die Schaltfläche Save jetzt *hervorgehoben* ist. Fahren Sie mit der Maus über die Schaltfläche Save, und Mavo hebt die Eigenschaften mit den *nicht gespeicherten Daten* hervor. Ist das nicht cool?

Klicken Sie auf die Schaltfläche Save und aktualisieren Sie die Seite (es ist nicht notwendig, vor dem Aktualisieren der Seite in den Lesemodus zu wechseln). Sind Ihre Daten immer noch da? Großartig! Wir sind unserem Ziel – einer voll funktionsfähigen Karteikarten-Anwendung – einen Schritt näher gekommen.

Das mv-autosave-Attribut

Müssen wir jetzt jedes Mal die Schaltfläche Save klicken, wenn wir möchten, dass unsere Daten gespeichert werden? Das mag sicherer sein, um die Zerstörung wertvoller Daten zu verhindern, kann aber oft unbequem sein. Können wir die Daten nicht einfach automatisch speichern? Sicher! Um die Daten jedes Mal automatisch zu speichern, wenn sie geändert werden, können wir das Attribut mv-autosave auf unserer Mavo-Root verwenden. Sein Wert ist die Anzahl der Sekunden, um das Speichern zu drosseln. Fügen wir mv-autosave="3" zum Root-Element unserer App hinzu

<main mv-app="flashcard" mv-storage="local" mv-autosave="3">
  ...
</main>

Ändern Sie die Daten ein weiteres Mal und schauen Sie sich die Schaltfläche Save an. Sehen Sie? Am Anfang war sie hervorgehoben, aber nach 3 Sekunden – nicht mehr. Alle unsere Daten sind jetzt automatisch gespeichert!

Der Hauptteil unserer App würde also so aussehen

<main mv-app="flashcards" mv-storage="local" mv-autosave="3">
  <article property="flashcard" mv-multiple>
    <p property="source">Word or phrase</p>
    <p property="translation">Translation</p>
  </article>
</main>
💻 Lasst uns die Hände schmutzig machen!

Wir sind fast mit der Alpha-Version unserer App fertig. Nun sind Sie an der Reihe, die App noch besser zu machen. Keine Sorge, Sie haben alles Wissen, das Sie brauchen.

Erweitern Sie die App so, dass Karteikarten von Endbenutzern in verschiedene Gruppen zu verschiedenen Themen organisiert werden können, z. B. können die Benutzer alle Karteikarten, die sich auf Kleidung beziehen, in einer Gruppe sammeln, alle Karteikarten, die sich auf Küchenutensilien beziehen, in der anderen usw.

💡 Hinweise!

Es gibt viele Wege, dieses Ziel zu erreichen, und es liegt an Ihnen zu entscheiden, welchen Weg Sie einschlagen. Ich möchte Sie jedoch bitten, vor dem Weitermachen über einige Fragen nachzudenken

  1. Welches HTML-Element würden Sie als Gruppierungselement verwenden? Es wäre praktisch für die Benutzer, wenn sie den Namen der Gruppe von Karteikarten (Thema) sehen und die Gruppe bis zum Titel einklappen könnten.
  2. Welches(e) Mavo-Attribut(e) werden Sie dem Element hinzufügen, falls vorhanden? Wird das Element eine Eigenschaft oder eine Sammlung sein?
  3. Werden Endbenutzer neue Themen hinzufügen, löschen und neu anordnen, den Titel eines Themas ändern und Karteikarten zwischen verschiedenen Themen verschieben können?

Was ist, wenn Sie sich entscheiden, Karteikarten nicht in Gruppen zu organisieren, sondern sie einfach mit Tags zu versehen, die verschiedenen Themen entsprechen? Nun, das ist vollkommen in Ordnung. Die Lösung mit Tags ist ebenfalls angemessen. Übungshalber versuchen Sie auch, diesen Ansatz zu verfolgen.

Das mv-bar-Attribut

See the Pen
05. Das mv-bar-Attribut
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Da unsere App die Daten lokal speichert, können die Benutzer der App standardmäßig ihre Karten nicht mit anderen Benutzern teilen. Wäre es nicht großartig, wenn wir ihnen erlauben würden, ihre Karteikarten zu exportieren und die Karteikarten von jemand anderem zu importieren? Glücklicherweise sind diese Funktionen bereits in Mavo implementiert und wir können sie sehr einfach zu unserer App hinzufügen!

Das Attribut mv-bar steuert, welche Schaltflächen in der Toolbar angezeigt werden, falls überhaupt. Es wird typischerweise auf der Mavo-Root (ein Element mit dem Attribut mv-app) angegeben. Schaltflächen werden durch ihre IDs dargestellt (die sehr logisch sind): edit, import, export, etc.

Da wir nur ein paar Schaltflächen zum Standardset hinzufügen möchten, können wir die sogenannte relative Syntax verwenden, die es uns ermöglicht, Schaltflächen zum Standardsatz hinzuzufügen und zu entfernen, ohne alles explizit auflisten zu müssen. Alles, was wir brauchen, ist, den Wert des Attributs mv-bar mit dem Schlüsselwort with zu beginnen.

Dadurch würden wir Folgendes erhalten

<main mv-app="flashcards"
      mv-storage="local"
      mv-autosave="3"
      mv-bar="with import export">
      ...
</main>
💻 Lasst uns die Hände schmutzig machen!

Probieren Sie diese Funktionen aus: Fügen Sie einige Karteikarten hinzu, versuchen Sie, sie in eine Datei zu exportieren. Löschen Sie dann vorhandene Karteikarten und importieren Sie die Karteikarten aus der zuvor exportierten Datei.

Ausdrücke und MavoScript

See the Pen
06. Ausdrücke und MavoScript
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Fügen wir nun einige Statistiken zu unserer App hinzu, wie z. B. die Anzahl der Karteikarten! Klingt interessant? Ich hoffe es. 😀

Dazu müssen wir etwas Neues über Mavo lernen.

Wir können dynamisch auf den Wert jeder von uns definierten Eigenschaft verweisen, überall *in unserer Mavo-App* (auch in HTML-Attributen), indem wir ihren Namen in Klammern setzen, so: [propertyName]. Dies ist ein Beispiel für einen einfachen Ausdruck, der es uns ermöglicht, Dinge dynamisch und reaktiv zu berechnen, während sie sich ändern.

Experimentieren wir nun und fügen wir einen [source]-Ausdruck *innerhalb* der Eigenschaft flashcard ein, z. B. zwischen zwei Eigenschaften: der source und der translation.

...
  <p property="source">Word or phrase</p>
  [source]
  <p property="translation">Translation</p>
...

Was hat sich an unserer App geändert? Der Wert der source-Eigenschaft der Karteikarte wird nun zweimal auf der Seite angezeigt.

Schalten Sie in den Bearbeitungsmodus und versuchen Sie, den Wert der source-Eigenschaft zu ändern. Können Sie das sehen? Der Seiteninhalt aktualisiert sich, während Sie den Wert der Eigenschaft ändern! Deshalb habe ich früher gesagt, dass Mavo es uns ermöglicht, reaktive Webanwendungen zu entwickeln.

Das ist in der Tat cool, aber in unserem Fall leider nicht wirklich hilfreich: Wir können diesen Ausdruck nicht verwenden, um die Anzahl der Karteikarten zu zählen – wir hätten immer nur *einen Wert*.

Was ist, wenn wir den [source]-Ausdruck *außerhalb* der flashcard-Eigenschaft platzieren? Wir hätten dann so etwas wie

...
  [source]
  <article property="flashcard" mv-multiple>
    ...
  </article>
...

Wie unterscheidet sich das vom vorherigen Fall? Um den Unterschied zu sehen, fügen Sie einige Karteikarten hinzu, falls Sie dies noch nicht getan haben. Anstelle von *einem Wert* haben wir nun *eine Liste von durch Kommas getrennten Werten*: der source-Eigenschaft *aller Karteikarten*. Das ist genau das, was wir gesucht haben: die Anzahl der Elemente in der Liste entspricht der Anzahl der Karteikarten in der App.

Macht das Sinn? Nun ja, aber wäre es nicht logischer, wenn wir die Anzahl der *Karteikarten* zählen würden und nicht die Anzahl der Werte ihrer source-Eigenschaft? Schließlich existiert eine hinzugefügte Karteikarte, noch bevor wir ihren Quelltext oder ihre Übersetzung ausfüllen. Ich schlage vor, Sie tun Folgendes: Ersetzen wir den Ausdruck [source] durch [flashcard]

...
  [flashcard]
  <article property="flashcard" mv-multiple>
    ...
  </article>
...

Den Unterschied bemerkt? Wir haben immer noch eine Liste, aber ihre Werte sind keine einfachen Werte, sondern *Objekte*, d. h. komplexe Werte, die alle Daten enthalten, die zu jeder Karteikarte gehören. Die gute Nachricht ist, dass die Anzahl dieser Objekte der Anzahl der Karteikarten entspricht, da für jede Karteikarte eines vorhanden ist, auch wenn sie komplett leer ist. Also, im Moment haben wir ein Objekt für jede Karteikarte, aber wie zählen wir sie und zeigen die Gesamtzahl an?

Machen wir uns nun mit den MavoScript-Funktionen vertraut und finden diejenige, die es uns ermöglicht, die Anzahl der Karteikarten zu zählen. Denken Sie daran, wir haben eine *Liste* von Karteikarten, also müssen wir eine Funktion finden, die es uns ermöglicht, die *Anzahl der Elemente in einer Liste zu zählen*. Und hier ist sie – die Funktion count() macht genau das!

Aber wie können wir Funktionen in Ausdrücken verwenden? Gibt es Regeln, die wir beachten müssen? Nun, ja, es gibt ein paar

  1. Ausdrücke werden durch Klammern gekennzeichnet.
  2. Verschachteln Sie keine Klammern.

Versuchen wir, die Funktion count() zu verwenden, um die Anzahl der Karteikarten zu zählen

...
[count(flashcard)]
<article property="flashcard" mv-multiple>
  ...
</article>
...

Und genau das haben wir angestrebt – jetzt haben wir einige Statistiken in unserer App! Ist das nicht cool?

💻 Lasst uns die Hände schmutzig machen!

Ich hoffe, Sie haben sich schon aufgewärmt und sind bereit, weiter mit Mavo zu experimentieren.

Verbessern Sie die Anwendung so, dass die Statistiken nicht nur für die Gesamtzahl der Karteikarten in der App angezeigt werden, sondern auch für die Anzahl der Karteikarten in jedem Thema separat, falls es Themen gibt.

💡 Hinweis!
Möchten Sie eine Liste anhand bestimmter Kriterien filtern? Der where-Operator wird Ihnen helfen.

Die Selbstbewertungsfunktion

Wir haben bereits eine Anwendung, mit der wir mehrere Karteikarten erstellen, bearbeiten und speichern können. Aber wie behalten wir den Überblick, welche wir bereits gelernt haben und welche wir noch üben müssen? Jede seriöse Karteikarten-Anwendung benötigt eine Selbstbewertungsfunktion. Lassen Sie uns untersuchen, wie wir diese hinzufügen können!

Angenommen, in unserer App haben wir zwei Schaltflächen für die Selbstbewertung: Bad und Good. Was genau soll jedes Mal passieren, wenn ein Endbenutzer die Schaltflächen klickt? Nun, die Idee ist ziemlich einfach

  • Das Klicken auf die Schaltfläche Bad würde bedeuten, dass der Benutzer das Wort noch nicht gelernt hat, und wir möchten, dass unsere App die entsprechende Karteikarte an den Anfang der Liste verschiebt, damit sie diese so schnell wie möglich nach dem Start der App sehen kann.
  • Das Klicken auf die Schaltfläche Good würde bedeuten, dass der Benutzer das Wort gelernt hat und die entsprechende Karteikarte ans Ende der Liste verschoben werden muss, damit er mit anderen Karteikarten arbeiten kann, die er noch nicht gelernt hat.

„Sind Sie sicher, dass wir das ohne JavaScript tun können?“, könnten Sie fragen. Ja! Mavo ist extrem leistungsfähig und kann uns mit allen Werkzeugen ausstatten, die wir brauchen!

Jetzt, wo wir wissen, was wir implementieren werden, richten wir zuerst die UI ein und gehen dann zum nächsten Schritt. Unsere Markup würde etwa so aussehen

...
<article property="flashcard" mv-multiple>
  ...
  <section>
    <h2>Evaluate Yourself</h2>
    <button>Bad</button>
    <button>Good</button>
  </section>
</article>
...

Das mv-action-Attribut

See the Pen
07. Das mv-action-Attribut
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Mavo-Aktionen ermöglichen es uns, eigene Steuerelemente zu erstellen, die Daten auf benutzerdefinierte Weise ändern, wenn der Benutzer mit ihnen interagiert. Klingt vielversprechend, oder?

Um eine benutzerdefinierte Aktion zu definieren, müssen wir das Attribut mv-action auf einem geeigneten Element innerhalb unserer Mavo-App verwenden. Die Aktion wird *jedes Mal ausgeführt, wenn das Element geklickt wird*. Das ist genau das, was wir gesucht haben.

Der Wert des Attributs mv-action ist ein Ausdruck. Wir können alle Ausdrucksfunktionen und die Syntax verwenden, die MavoScript uns bietet, sowie einige weitere zur Erleichterung der Datenmanipulation, wie z. B. add(), set(), move() oder delete(). Es ist wichtig zu beachten, dass diese Ausdrücke im Gegensatz zu normalen Ausdrücken, die reaktiv ausgewertet werden, nur jedes Mal ausgewertet werden, wenn die Aktion ausgelöst wird.

Wir müssen also Karteikarten innerhalb der Sammlung verschieben, und Mavo hat eine entsprechende Funktion, die uns das ermöglicht – die Funktion move(). Ihr erstes Argument bezieht sich auf das zu verschiebende Element, und das zweite ist seine Position in der Sammlung. Beachten Sie, dass die Elemente der Sammlung ab 0 nummeriert sind.

Lassen Sie uns den ersten Punkt der zuvor besprochenen Gliederung implementieren: Beim Selbstbewerten klickt ein Endbenutzer auf die Schaltfläche Bad und die entsprechende Karteikarte wird an den Anfang der Sammlung verschoben, d. h. sie wird zur ersten. Also im Code haben wir

...
<article property="flashcard" mv-multiple>
  ...
  <button mv-action="move(flashcard, 0)">Bad</button>
  ...
</article>
...

Beachten Sie, dass wir im Attribut mv-action uns auf die Eigenschaft flashcard *innerhalb* der Eigenschaft selbst beziehen, da wir uns mit der aktuellen Karteikarte befassen wollen.

Wenn wir versuchen, den zweiten Punkt der Gliederung zu implementieren, werden wir auf ein Problem stoßen. Können Sie vorschlagen, welches Problem das genau sein wird?

Erinnern wir uns, dass, wenn ein Endbenutzer auf die Schaltfläche Good klickt, die entsprechende Karteikarte ans Ende der Sammlung verschoben wird, d. h. sie wird zur letzten. Um eine Karteikarte zur letzten in der Sammlung zu machen, müssen wir die Anzahl der Elemente darin kennen.

Glücklicherweise haben wir diese Aufgabe bereits vor einiger Zeit gelöst und die entsprechende Funktion implementiert. Aber könnten wir diese Lösung verwenden, um unser aktuelles Problem zu lösen? Leider können wir das nicht: Wie wir bereits wissen, können wir auf die Sammlung von Karteikarten über ihren Namen verweisen (und ihre Größe auswerten) nur *außerhalb* der Karteikarteneigenschaft. Aber in unserem Fall müssen wir das innerhalb tun: die Schaltfläche Good, für die wir einen Ausdruck schreiben müssen, befindet sich innerhalb der flashcard-Eigenschaft.

Was sollen wir also tun? Ich bin froh, dass Sie fragen. Mavo hat die Lösung.

Verwendung des <meta>-Elements zur Speicherung von Zwischenwerten

See the Pen
08. Das <meta>-Element
by Dmitry Sharabin (@dsharabin)
auf CodePen.

Einerseits wissen wir also, dass der Ausdruck [count(flashcards)] uns die Anzahl der Karteikarten liefert, *wenn* er *außerhalb* der Karteikarteneigenschaft ausgewertet wird. Andererseits müssen wir diesen Wert *innerhalb* der Karteikarteneigenschaft verwenden.

Um dieses Dilemma zu lösen, müssen wir die Anzahl der Karteikarten außerhalb der flashcard-Eigenschaft auswerten und das Ergebnis irgendwie speichern, um es woanders in der App, genau innerhalb der flashcard-Eigenschaft, verwenden zu können. Für solche Fälle gibt es in Mavo sogenannte berechnete Eigenschaften.

Um ein Zwischenergebnis zu speichern, auf das wir verweisen können, benötigen wir ein HTML-Element in unserem Code. Es wird empfohlen, für diesen Zweck das <meta>-Element zu verwenden, wie folgt: <meta property="propertyName" content="[expression]">. Der Vorteil der Verwendung dieses Elements ist, dass es sowohl semantisch als auch visuell außerhalb des Bearbeitungsmodus ausgeblendet wird.

Fügen wir nun die berechnete Eigenschaft flashcardCount zu unserer App hinzu. Denken Sie daran, dass wir sie außerhalb der Eigenschaft flashcard platzieren müssen, aber dann können wir von überall darauf verweisen.

...
<meta property="flashcardCount" content="[count(flashcard)]">
<article property="flashcard" mv-multiple>
    ...
</article>
...

Nur noch ein Schritt, um die Implementierung der Selbstbewertungsfunktion abzuschließen: Wenn ein Endbenutzer auf die Schaltfläche Gut klickt, wird die entsprechende Karteikarte ans Ende der Sammlung verschoben, d. h. sie wird zur letzten. Fügen wir die entsprechende Aktion in den Code unserer App ein.

...
<meta property="flashcardCount" content="[count(flashcard)]">
<article property="flashcard" mv-multiple>
  ...
  <button mv-action="move(flashcard, flashcardCount)">Good</button>
</article>
...

Wir sind fertig! Herzlichen Glückwunsch! 😀

💻 Lasst uns die Hände schmutzig machen!

Es gibt noch eine weitere Möglichkeit, diese Aufgabe zu lösen: mit Hilfe der speziellen Eigenschaft $all. Die Eigenschaft $all repräsentiert eine Sammlung selbst, wenn sie sich innerhalb der Sammlung befindet. Daher ist in diesem Fall keine berechnete Eigenschaft erforderlich. Versuchen Sie, diese Lösung selbst zu implementieren.

Es gibt nur noch eine kleine Sache zu beheben. Erinnern Sie sich an den Teil, in dem wir unserer App einige Statistiken hinzugefügt haben? Erinnern Sie sich an den Ausdruck, den wir erstellt haben, um die Anzahl der Karteikarten in der App zu ermitteln: [count(flashcard)]? Stattdessen können (und sollten) wir jetzt die von uns definierte berechnete Eigenschaft verwenden. Nehmen Sie die entsprechenden Änderungen in der App vor.

Fazit

Was haben wir also bisher gelernt? Fassen wir zusammen. Um jede beliebige statische HTML-Seite in eine Mavo-App zu verwandeln, müssen wir:

  1. Fügen Sie die Mavo JavaScript- und CSS-Dateien in den <head>-Bereich der Seite ein.
  2. Fügen Sie das Attribut mv-app zum Mavo-Root-Element hinzu.
  3. Teilen Sie Mavo mit, welche Elemente unserer App wichtig sind, indem Sie ihnen das Attribut property hinzufügen.
  4. Platzieren Sie das Attribut mv-multiple auf dem Element, das vervielfältigt und in eine Sammlung umgewandelt werden soll.
  5. Teilen Sie Mavo mit, wo unsere Daten gespeichert werden sollen, indem Sie das Attribut mv-storage zum Mavo-Root hinzufügen.
  6. Entscheiden Sie, ob Mavo unsere Daten automatisch speichern soll oder nicht. Wenn ja, fügen Sie das Attribut mv-autosave zum Mavo-Root hinzu.

    Wir wissen auch, dass

  7. Die Mavo-Toolbar ist vollständig anpassbar. Das Attribut mv-bar steuert, welche Schaltflächen dort erscheinen.
  8. Ausdrücke ermöglichen es uns, den aktuellen Wert von Eigenschaften in anderen Elementen darzustellen und Berechnungen durchzuführen. Der Wert (und Typ) eines Ausdrucks variiert je nach dem Ort, an dem der Ausdruck im Code steht. Mavos Syntax für Ausdrücke wird MavoScript genannt.
  9. Benutzerdefinierte Aktionen ermöglichen die Erstellung von Steuerelementen, die Daten auf benutzerdefinierte Weise ändern. Um eine benutzerdefinierte Aktion zu definieren, setzen Sie das Attribut mv-action auf ein geeignetes Element innerhalb einer Mavo-App.
  10. Eigenschaften, deren Werte Ausdrücke sind, werden als berechnete Eigenschaften bezeichnet. Um ein Zwischenergebnis zu speichern, auf das an anderer Stelle in der App verwiesen werden kann, wird die Verwendung des <meta>-Elements empfohlen.

Anstelle eines Epilogs

Wir haben also unsere App erstellt. Ist sie schon perfekt? Natürlich nicht, nichts ist perfekt! Es gibt so viele Dinge, die verbessert werden können, und so viele Funktionen, die hinzugefügt werden können (mit Hilfe von Mavo können wir unsere App sogar mehrsprachig machen!). Machen Sie weiter, verbessern Sie sie noch mehr, zögern Sie nicht, etwas Neues auszuprobieren!

Was wir bisher über Mavo gelernt haben, ist nur die Spitze des Eisbergs, und es gibt noch viel mehr. Ich ermutige Sie, sich näher damit zu befassen, indem Sie die Dokumentation lesen, Beispiele untersuchen (auf der Mavo-Website oder auf CodePen: erstellt von Lea Verou und einige von mir) und neue Dinge erstellen! Viel Erfolg! 😉

Danksagungen

Ich möchte zwei großartige Leute danken. Zunächst einmal mein riesiger Dank an Lea Verou, die mich nicht nur dazu inspiriert hat, dieses Tutorial zu schreiben (und mir geholfen hat, es zu ermöglichen), sondern mich auch ständig inspiriert, wie sie die Welt der Webentwicklung zu einem besseren Ort macht. Ich habe noch nie einen so begabten Menschen getroffen und freue mich über die Gelegenheit, mit ihr einige Dinge zu machen!

Ich danke auch James Moore. Die Beispiele, die er in seinem Kurs „Functional Programming for Beginners with JavaScript“ auf Udemy verwendet, haben mich dazu gebracht, meine ganz eigene Version einer Karteikarten-Lern-App zu erstellen. Er ist ein wundervoller Lehrer!