In meinem einleitenden Artikel ging ich auf die Grundlagen des Ember.js-Frameworks und die grundlegenden Konzepte für das Erstellen einer Ember-Anwendung ein. In diesem Folgeartikel werden wir tiefer in bestimmte Bereiche des Frameworks eintauchen, um zu verstehen, wie viele der Funktionen zusammenwirken, um die Komplexität der Entwicklung von Einzelseitenanwendungen zu abstrahieren.
Ich habe zuvor festgestellt, dass der einfachste Weg, die benötigten Dateien zu erhalten, darin besteht, zum Github-Repo von Ember.js zu gehen und das Start-Kit herunterzuziehen, und das gilt immer noch. Dieses Boilerplate-Kit enthält alle Dateien, die Sie benötigen, um Ihre Ember-Erfahrung in Schwung zu bringen. Laden Sie sie daher unbedingt aus diesem Artikel herunter.
Das Interessante ist, dass das Starter-Kit auch ein hervorragendes Beispiel für eine sehr einfache Ember-App ist. Gehen wir es durch, um zu verstehen, was los ist. Beachten Sie, dass ich mich später genauer mit bestimmten Bereichen beschäftigen werde. Machen Sie sich also keine Sorgen, wenn in diesem Abschnitt etwas nicht sofort sinnvoll ist. Sie erhalten ein umfassendes Verständnis der Funktionalität, bevor Sie in die Details eintauchen.
Öffnen index.html
In Ihrem Browser sehen Sie Folgendes:
Willkommen bei Ember.js
Ich weiß, das ist nicht sehr aufregend, aber wenn Sie sich den Code ansehen, der das gerendert hat, werden Sie feststellen, dass er mit sehr wenig Aufwand erledigt wurde. Wenn wir "js / app.js" betrachten, sehen wir den folgenden Code:
App = Ember.Application.create (); App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['red', 'yellow', 'blue']););
Grundsätzlich benötigt eine Ember-App nur diese eine Zeile, um technisch als "App" zu gelten:
App = Ember.Application.create ();
Dieser Code richtet eine Instanz des Ember-Anwendungsobjekts sowie eine Standardanwendungsvorlage, Ereignis-Listener und Anwendungsrouter ein. Nehmen Sie sich eine Sekunde Zeit und denken Sie an den Code, den Sie normalerweise schreiben müssten, um einen globalen Namespace und eine clientseitige Vorlage zu erstellen, Ereignisbehandlungsroutinen für die globale Benutzerinteraktion zu binden und die Verlaufs- und Statusverwaltung in Ihren Code aufzunehmen. Ja, diese eine Zeile macht das alles. Um es klar zu sagen: Ich sage nicht, dass es die ganze Arbeit für Sie erledigt, aber es schafft die Grundlage, auf der Sie aufbauen, und zwar mit einem Methodenaufruf.
Der nächste Code legt das Verhalten einer Route in diesem Fall für die Hauptleitung fest index.html
Seite:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['red', 'yellow', 'blue']););
Denken Sie daran, dass Routen zur Verwaltung der Ressourcen verwendet werden, die mit einer bestimmten URL in der Anwendung verknüpft sind, und es Ember ermöglicht, die verschiedenen Status der einzelnen Seiten zu verfolgen. Die URL ist die Schlüsselkennung, mit der Ember erkennt, welcher Anwendungsstatus dem Benutzer angezeigt werden muss.
In diesem Fall wird die Stammroute standardmäßig in Ember erstellt. Ich hätte die Route auch explizit so definieren können:
App.Router.map (function () this.resource ('index', path: '/'); // bringt uns zu "/");
Aber Ember kümmert sich für mich um die "Wurzel" meiner Bewerbung. Wir werden die Routen später detaillierter angehen.
Gehen Sie zurück zu folgendem Code:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['red', 'yellow', 'blue']););
In diesem Fall richtet Ember einen Controller ein, der einen Beispieldatensatz mit einem semantischen Namen lädt, wenn ein Benutzer den Stamm der Site trifft Inhalt
. Diese Daten können später in der App über diesen Controller mit diesem Namen verwendet werden. Und genau das passiert in index.html
. Öffnen Sie die Datei und Sie finden Folgendes:
Dies ist eine clientseitige Handlebars-Vorlage. Denken Sie daran, dass Handlebars die Vorlagenbibliothek für Ember ist und für die Erstellung datengesteuerter Benutzeroberflächen für Ihre App unerlässlich ist. Ember verwendet Datenattribute, um diese Vorlagen mit den Steuerungen zu verknüpfen, die Ihre Daten verwalten, unabhängig davon, ob sie über eine Route oder als eigenständige Steuerung angegeben werden.
In meinem letzten Artikel habe ich erwähnt, dass Namenskonventionen in Ember wichtig sind und das Verbinden von Features erleichtern. Wenn Sie sich den Code der Vorlage ansehen, wird der Name der Vorlage (über das Symbol angegeben) angezeigt Datenvorlagenname Attribut) ist "Index". Dies ist zweckmäßig und soll die Verbindung zu dem Controller erleichtern, der in der Route mit demselben Namen angegeben ist. Wenn wir uns den Routencode noch einmal ansehen, werden Sie feststellen, dass er "IndexRoute" genannt wird und in dem sich ein Controller befindet, dessen Daten eingestellt sind:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['red', 'yellow', 'blue']););
Der Controller legt eine Datenquelle mit dem Namen "content" fest und lädt sie mit einem Array von Zeichenfolgen für die Farben. Im Grunde handelt es sich bei dem Array um Ihr Modell, und der Controller wird verwendet, um diese Attribute des Modells verfügbar zu machen.
Die Namenskonventionen ermöglichen es Ember, die Ressourcen dieser Route (z. B. die Steuerung mit Daten) mit der Vorlage zu verknüpfen, die unter demselben Namen angegeben ist. Dadurch erhält die Vorlage Zugriff auf die vom Controller bereitgestellten Daten, sodass sie mithilfe der Handlebars-Anweisungen gerendert werden kann. Von dort werden die Elemente im Array mit Handlebars übergangen. jeder Direktive und Angabe des Alias Modell- was auf die Datenquelle verweist:
# Jedes Element im Modell
Genauer gesagt, die Daten werden in dynamisch erstellte Listenelemente eingefügt und erzeugen so die Markup-Funktion für Sie. Das ist das Schöne an clientseitigen Vorlagen.
Ich denke, diese grundlegende App zeigt, wie Ember eine Menge Dinge für Sie abstrahiert. Es ist zwar ein bisschen schwarze Magie und es ist nicht immer leicht zu verstehen, wie die Dinge funktionieren. Das ist mir tatsächlich passiert und die Dinge haben zuerst nicht ganz geklickt. Sobald Sie die Beziehungen zwischen den verschiedenen Komponenten des Frameworks verstehen, wird es sinnvoller. Beginnen wir von Grund auf, um dies besser zu verstehen.
Ich habe kurz das Ember-Anwendungsobjekt angesprochen und die Tatsache, dass es die Grundlage für Ihre Anwendung bildet. Die Ember-Handbücher geben eine ausgezeichnete Arbeit, um genau zu beschreiben, was ein Ember-Anwendungsobjekt instantiiert:
App.PostsView
und App.PostsController
). Dies trägt dazu bei, die Umweltverschmutzung zu verhindern. Also diese einfache Aussage:
App = Ember.Application.create ();
verkabelt eine Menge von grundlegenden Elementen, von denen Ihre Anwendung abhängen wird. Es ist wichtig, das zu beachten App ist kein Schlüsselwort in Ember. Es ist eine normale globale Variable, die Sie zum Definieren des Namespaces verwenden, und es kann sich um einen beliebigen gültigen Variablennamen handeln. Von dem, was ich gesehen habe, der Variablenname, App, ist eine häufig verwendete Konvention in den meisten Ember-Apps und wird tatsächlich empfohlen, um das Kopieren und Einfügen eines großen Teils des in der Community erstellten Beispielcodes zu erleichtern.
Wenn Sie die obige Liste verwenden, erstellt Ember über diese eine Zeile im Wesentlichen diesen Code für Sie automatisch hinter den Kulissen:
// Erstellen Sie den Anwendungsnamespace App = Ember.Application.create (); // Erstellen Sie den globalen Router, um den Seitenstatus über URLs zu verwalten. App.Router.map (function () ); // Erstellen Sie die Standardanwendungsroute, um Statuseigenschaften auf Anwendungsebene festzulegen. App.ApplicationRoute = Ember.Route.extend (); // Erstellen Sie die Standardanwendungsvorlage
Während das Starter-Kit einen Router, eine Route oder eine Vorlage für einen Anwendungsbereich nicht explizit definiert hat, hat Ember sichergestellt, dass diese erstellt und verfügbar sind, sodass die Grundlage Ihrer App festgelegt und für Sie verfügbar ist. Es ist definitiv in Ordnung, den Code explizit zu erstellen. Möglicherweise möchten Sie dies auch tun, wenn Sie Daten übergeben oder Attribute für Ihre Instanz des Anwendungsobjekts festlegen möchten.
Jetzt fragen Sie sich vielleicht, ob diese "Anwendungsvorlage" automatisch gerendert wird und warum Sie sie nicht sehen index.html
. Das liegt daran, dass es optional ist, explizit das zu erstellen Anwendung Vorlage. Wenn es sich im Markup befindet, wird es von Ember sofort gerendert. Andernfalls werden andere Teile Ihrer Anwendung wie gewöhnlich verarbeitet. Der typische Anwendungsfall für die Anwendung template definiert globale, anwendungsweite Elemente der Benutzeroberfläche, z. B. Kopf- und Fußzeilen.
Definieren der Anwendung template verwendet dieselbe Stilsyntax wie jede andere Vorlage, mit einem kleinen Unterschied: Der Name der Vorlage muss nicht angegeben werden. So definieren Sie Ihre Vorlage folgendermaßen:
oder dieses:
gibt Ihnen die gleichen exakten Ergebnisse. Ember interpretiert eine Vorlage mit Nein Datenvorlagenname als Anwendungsvorlage und rendert sie automatisch beim Start der Anwendung.
Wenn Sie aktualisieren index.html
indem Sie diesen Code hinzufügen:
Sie sehen nun, dass der Inhalt des Header-Tags über dem Inhalt der Indexvorlage angezeigt wird. Die Lenker Auslauf Direktive dient als Platzhalter in der Anwendung Template, mit dem Ember andere Templates einbetten kann (die als Art von Wrapper dienen), und Sie können globale UI-Funktionen wie Kopf- und Fußzeilen verwenden, die Ihren Inhalt und Ihre Funktionalität umgeben. Durch das Hinzufügen der Anwendung Vorlage an index.html
, Sie haben Ember angewiesen:
Auslauf
RichtlinieIndex
Vorlage Ein wichtiger Aspekt ist, dass wir lediglich eine Vorlage hinzugefügt haben (Anwendung) und Ember kümmerte sich sofort um den Rest. Es sind diese Feature-Bindungen, die Ember.js zu einem leistungsstarken Framework machen, mit dem gearbeitet werden kann.
Das Routing ist in Ember wohl das am schwersten zu verstehende Konzept, daher werde ich mein Bestes tun, um es in überschaubaren Schritten aufzulösen. Wenn ein Benutzer in Ihrer Anwendung navigiert, muss es eine Methode zum Verwalten des Status der verschiedenen Teile geben, die der Benutzer besucht. Hier kommen der Router und die standortspezifischen Routen der Anwendung ins Spiel.
Das Ember-Routerobjekt verwaltet dies durch die Verwendung von Routen, die die für Spezifikationsspeicherorte benötigten Ressourcen identifizieren. Ich stelle mir den Router gerne als Verkehrspolizist vor, der Autos (Benutzer) auf verschiedene Straßen (URLs & Routen) leitet. Die Routen selbst sind an bestimmte URLs gebunden. Wenn auf die URL zugegriffen wird, werden die Routenressourcen verfügbar gemacht.
Anschauen js / app.js
Sie werden wieder feststellen, dass für die Stammseite eine Route erstellt wurde (Index):
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['red', 'yellow', 'blue']););
Es gibt jedoch keine Router-Instanz. Denken Sie daran, dass Ember standardmäßig einen Router erstellt, wenn Sie keinen Router angeben. Es wird auch ein Standardrouteneintrag für das Stammverzeichnis der Anwendung erstellt, der folgendermaßen aussieht:
App.Router.map (function () this.resource ('index', path: '/'););
Dies teilt Ember mit, dass bei einem Treffer des Stammes der Anwendung die Ressourcen einer aufgerufenen Routenobjektinstanz geladen werden sollten IndexRoute wenn es verfügbar ist Daher wird die Anwendung trotz der Deklaration einer Router-Instanz weiterhin ausgeführt. Glut weiß intern, dass die Wurzelroute benannt werden sollte IndexRoute, wird danach suchen und seine Ressourcen entsprechend laden. In diesem Fall wird ein Controller erstellt, der Daten enthält, die in der Indexvorlage verwendet werden sollen.
Da es sich bei URLs um die Schlüsselbezeichner handelt, die Ember zur Verwaltung des Status Ihrer Anwendung verwendet, wird normalerweise für jede URL ein eigener Routenhandler angegeben, wenn Ressourcen für diesen Abschnitt der App geladen werden müssen. Hier ist was ich meine; Angenommen, Sie haben eine App mit drei Abschnitten:
In den meisten Fällen hat jeder dieser Abschnitte seine eigenen einzigartigen Ressourcen, die geladen werden müssen (z. B. Daten oder Bilder). Sie erstellen also Routen-Handler mit der Ressource() Methode in der Anwendungsrouter-Instanz von Ember wie folgt:
App.Router.map (function () this.resource ('accounts'); this.resource ('profiles'); this.resource ('gallery'););
Auf diese Weise kann Ember die Struktur der Anwendung verstehen und die Ressourcen entsprechend verwalten. Die Routendefinitionen korrelieren mit einzelnen Routenobjektinstanzen, die das schwere Heben übernehmen, z. B. das Einrichten oder Anschließen von Controllern:
App.GalleryRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['pic-1.png', 'pic-2.png', 'pic-3.png' ]););
Wenn ein Benutzer im obigen Beispiel "/ gallery" besucht, instanziiert Ember.js das Routenobjekt "GalleryRoute", richtet einen Controller mit Daten ein und rendert das Galerie Vorlage. Deshalb sind Namenskonventionen in Ember so wichtig.
Ihre Anwendung kann auch geschachtelte URLs enthalten, z / Konto / neu
Für diese Fälle können Sie Ember-Ressourcen definieren, mit denen Sie Routen wie folgt zusammenfassen können:
App.Router.map (function () this.resource ('accounts', function () this.route ('new');););
In diesem Beispiel haben wir die verwendet Ressource()
Methode zum Gruppieren der Routen und der Route()
Methode zur Definition der Routen innerhalb der Gruppe. Die Faustregel ist zu verwenden Ressource()
für Nomen (Konten und Konten wären selbst Ressourcen, wenn sie verschachtelt sind) und Route()
für Modifikatoren: (Verben wie Neu
und bearbeiten
oder Adjektive wie Favoriten
und Sternchen
).
Neben der Gruppierung der Routen erstellt Ember interne Verweise auf die Controller, Routen und Vorlagen für jede der angegebenen Gruppenrouten. So würde es aussehen (und wieder berührt es Embers Namenskonventionen):
"/Konten":
"/ accounts / new":
Wenn ein Benutzer "/ accounts / new" besucht, kommt es zu einem Parent / Child- oder Master / Detailszenario. Ember wird zuerst sicherstellen, dass die Ressourcen für Konten sind verfügbar und machen das Konten Vorlage (dies ist der Master-Teil davon). Dann wird es nachgehen und dasselbe für "/ accounts / new" tun, Ressourcen einrichten und die Konten.neu Vorlage.
Beachten Sie, dass Ressourcen auch für viel tiefere URL-Strukturen verschachtelt werden können, z.
App.Router.map (function () this.resource ('accounts', function () this.route ('new'); this.resource ('pictures', function () this.route ('add') ););););
Ich habe in diesem Beitrag viel Material behandelt. Hoffentlich hat es dazu beigetragen, einige Aspekte der Funktionsweise einer Ember-Anwendung und der Funktionsweise von Routen zu vereinfachen.
Wir sind aber noch nicht fertig. Im nächsten Eintrag werde ich auf die Funktionen von Ember eingehen, mit denen Sie Daten zurückholen und mit Ihrer App verfügbar machen können. Hier kommen Modelle und Controller ins Spiel, also konzentrieren wir uns darauf, zu verstehen, wie die beiden zusammenarbeiten.