Dans mon article d'introduction, j'ai passé en revue les bases du framework Ember.js et les concepts de base pour la construction d'une application Ember. Dans cet article de suivi, nous allons approfondir des domaines spécifiques du cadre pour comprendre combien de fonctionnalités travaillent ensemble pour résumer les complexités du développement d'applications d'une seule page..
J'ai déjà noté que le moyen le plus simple d'obtenir les fichiers dont vous avez besoin est de consulter le référentiel Ember.js Github et de dérouler le kit de démarrage, ce qui est toujours vrai. Ce kit standard comprend tous les fichiers dont vous aurez besoin pour relancer votre expérience Ember. Assurez-vous donc de le télécharger à partir de cet article..
La chose intéressante est que le kit de démarrage est également un excellent exemple d'application très basique Ember. Passons en revue pour comprendre ce qui se passe. Notez que je creuserai plus tard dans des domaines spécifiques, alors ne vous inquiétez pas si quelque chose n'a pas de sens immédiat dans cette section. C’est plus pour vous donner une compréhension de haut niveau de la fonctionnalité avant de plonger dans les détails.
Ouvrir index.html
dans votre navigateur, vous verrez ce qui suit:
Bienvenue sur Ember.js
Ce n'est pas très excitant, je le sais, mais si vous regardez le code qui a rendu cela, vous verrez que cela a été fait avec très peu d'effort. Si nous regardons "js / app.js", nous voyons le code suivant:
App = Ember.Application.create (); App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('contenu', ['rouge', 'jaune', 'bleu']););
Au niveau le plus élémentaire, une application Ember n'a besoin que de cette ligne pour être considérée techniquement comme une "application":
App = Ember.Application.create ();
Ce code configure une instance de l'objet d'application Ember, ainsi qu'un modèle d'application par défaut, des écouteurs d'événement et un routeur d'application. Prenez une seconde et essayez de penser au code que vous auriez normalement à écrire pour créer un espace de noms global, un modèle côté client, des gestionnaires d'événements de liaison pour une interaction utilisateur globale et inclure la gestion de l'historique et de l'état dans votre code. Oui, cette ligne fait tout cela. Soyons clairs, cependant: je ne dis pas que tout le travail est fait pour vous, mais cela crée la base sur laquelle vous allez construire, via un appel de méthode..
L’ensemble de code suivant définit le comportement d’une route, dans ce cas, pour le principal index.html
page:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('contenu', ['rouge', 'jaune', 'bleu']););
N'oubliez pas que les itinéraires sont utilisés pour gérer les ressources associées à une URL spécifique dans l'application et permettent à Ember de suivre les différents états de pages individuelles. L'URL est l'identifiant de clé qu'Ember utilise pour comprendre quel état d'application doit être présenté à l'utilisateur..
Dans ce cas, la route racine est créée par défaut dans Ember. J'aurais pu aussi explicitement définir l'itinéraire de cette façon:
App.Router.map (function () this.resource ('index', path: '/'); // nous amène à "/");
Mais Ember s’occupe de cela pour moi comme de la "racine" de mon application. Nous aborderons les itinéraires plus en détail plus tard.
Revenons au code suivant:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('contenu', ['rouge', 'jaune', 'bleu']););
Dans ce cas, lorsqu'un utilisateur atteindra la racine du site, Ember installera un contrôleur qui chargera un échantillon de données avec un nom sémantique, appelé contenu
. Ces données peuvent ensuite être utilisées dans l'application, via ce contrôleur utilisant ce nom. Et c'est précisément ce qui se passe dans index.html
. Ouvrez le fichier et vous trouverez ce qui suit:
Ceci est un modèle client du guidon. N'oubliez pas que Handlebars est la bibliothèque de modèles pour Ember et qu'il est essentiel pour la création d'interfaces utilisateur pilotées par les données pour votre application. Ember utilise des attributs de données pour lier ces modèles aux contrôleurs qui gèrent vos données, qu'ils soient spécifiés via un itinéraire ou en tant que contrôleur autonome..
Dans mon dernier article, j'ai mentionné que les conventions de dénomination sont importantes dans Ember et qu'elles facilitent la connexion. Si vous regardez le code du modèle, vous verrez que le nom du modèle (spécifié via le nom de modèle de données attribut) est "index". Cela est utile et vise à faciliter la connexion au contrôleur spécifié dans la route du même nom. Si nous regardons à nouveau le code de la route, vous verrez qu'il s'appelle "IndexRoute" et qu'il contient un contrôleur avec des données en cours de définition:
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('contenu', ['rouge', 'jaune', 'bleu']););
Le contrôleur définit une source de données nommée "contenu" et la charge avec un tableau de chaînes pour les couleurs. Fondamentalement, le tableau est votre modèle et le contrôleur est utilisé pour exposer ces attributs du modèle..
Les conventions de dénomination permettent à Ember de lier les ressources de cette route (par exemple: le contrôleur avec les données) au modèle spécifié par le même nom. Cela donne au modèle l’accès aux données exposées par le contrôleur afin qu’il puisse le restituer à l’aide des directives du guidon. À partir de là, les éléments du tableau sont bouclés à l’aide des poignées. chaque directive et spécifiant l'alias modèle qui pointe vers la source de données:
#chaque article dans le modèle
Pour être plus précis, les données sont renseignées dans des éléments de liste créés dynamiquement, générant ainsi le balisage pour vous à la volée. C'est la beauté des modèles côté client.
Je pense que cette application de base montre comment Ember fait abstraction de nombreuses choses pour vous. C'est un peu de magie noire et il n'est pas toujours facile de comprendre comment les choses fonctionnent. En fait, cela m'est arrivé et les choses n'ont pas tout à fait cliqué au début. Une fois que vous commencez à comprendre les relations entre les différentes composantes du cadre, cela commence à avoir plus de sens. Partons du sol pour mieux comprendre cela..
J'ai brièvement abordé l'objet d'application Ember et le fait qu'il constitue la base de votre application. Les guides Ember font un excellent travail en décrivant spécifiquement ce que fait l'instanciation d'un objet d'application Ember:
App.PostsView
et App.PostsController
). Cela aide à éviter de polluer la portée mondiale. Donc, cette simple déclaration:
App = Ember.Application.create ();
câble une tonne de pièces fondamentales sur lesquelles votre application dépendra. Il est important de noter que App n'est pas un mot clé dans Ember. Il s’agit d’une variable globale normale que vous utilisez pour définir l’espace de nom. Ce nom peut être n’importe quel nom de variable valide. D'après ce que j'ai vu, le nom de la variable, App, est une convention couramment utilisée dans la plupart des applications Ember et est en fait recommandée pour faciliter la copie et le collage de la plupart des exemples de code créés dans la communauté..
En prenant la liste ci-dessus, ce que fait Ember, via cette ligne, consiste essentiellement à créer ce code pour vous automatiquement dans les coulisses:
// Créer l'espace de nom de l'application App = Ember.Application.create (); // Crée le routeur global pour gérer l'état de la page via des URL App.Router.map (function () ); // Créer la route d'application par défaut pour définir les propriétés d'état au niveau de l'application App.ApplicationRoute = Ember.Route.extend (); // Créer le modèle d'application par défaut
Ainsi, alors que le kit de démarrage ne définissait pas explicitement un routeur, un itinéraire ou un modèle au niveau de l'application, Ember s'est assuré qu'ils sont créés et disponibles de sorte que les bases de votre application soient définies et disponibles. C'est définitivement correct de créer explicitement le code. En fait, vous pouvez le faire si vous envisagez de transmettre des données ou de définir des attributs pour votre instance de l'objet d'application..
Maintenant, vous vous demandez peut-être que ce "modèle d'application" est automatiquement rendu et pourquoi vous ne le voyez pas dans index.html
. En effet, il est facultatif de créer explicitement le application modèle. Si c'est dans le balisage, Ember le rendra immédiatement. Sinon, les autres parties de votre application sont traitées normalement. Le cas d’utilisation typique du application le modèle définit les éléments d'interface utilisateur globaux, à l'échelle de l'application, tels que l'en-tête et les pieds de page.
Définir le application template utilise la même syntaxe de style que n'importe quel autre modèle, à une petite différence près: le nom du modèle n'a pas besoin d'être spécifié. Définissez votre modèle comme ceci:
ou ca:
vous donne les mêmes résultats exacts. Ember interprétera un modèle sans nom de modèle de données en tant que modèle d'application et le rendra automatiquement au démarrage de l'application.
Si vous mettez à jour index.html
en ajoutant ce code:
Vous verrez maintenant que le contenu de la balise d’en-tête apparaît au-dessus du contenu du modèle d’index. Le guidon sortie directive sert d'espace réservé dans la application template, permettant à Ember d'y injecter d'autres modèles (servant de wrapper de tris), et vous permettant de disposer de fonctionnalités d'interface utilisateur globales telles que les en-têtes et les pieds de page entourant votre contenu et vos fonctionnalités. En ajoutant le application modèle à index.html
, vous avez demandé à Ember de:
sortie
directifindice
modèle Une chose importante à retenir est que tout ce que nous avons fait a été d’ajouter un modèle (application), et Ember a immédiatement pris soin du reste. Ce sont ces liaisons de fonctionnalités qui font d’Ember.js un cadre puissant à utiliser..
Le routage est sans doute le concept le plus difficile à comprendre dans Ember, aussi je ferai de mon mieux pour le décomposer en étapes gérables. Lorsqu'un utilisateur navigue dans votre application, il doit exister une méthode de gestion de l'état des différentes parties visitées par l'utilisateur. C'est là que le routeur de l'application et les itinéraires spécifiques à l'emplacement entrent en jeu.
L'objet routeur Ember est ce qui gère cela via l'utilisation de routes qui identifient les ressources nécessaires pour les emplacements de spécification. J'aime penser au routeur comme à un agent de la circulation qui dirige les voitures (utilisateurs) vers différentes rues (URL et itinéraires). Les itinéraires, eux-mêmes, sont liés à des URL spécifiques et, lors de l'accès à l'URL, les ressources des itinéraires sont mises à disposition..
Regarder js / app.js
encore une fois, vous remarquerez qu’une route a été créée pour la page racine (indice):
App.IndexRoute = Ember.Route.extend (setupController: function (controller) controller.set ('contenu', ['rouge', 'jaune', 'bleu']););
Cependant, il n'y a pas d'instance de routeur. N'oubliez pas qu'Ember créera un routeur par défaut si vous n'en spécifiez pas. Cela créera également une entrée de route par défaut pour la racine de l'application, semblable à ceci:
App.Router.map (function () this.resource ('index', path: '/'););
Ceci indique à Ember que, lorsque la racine de l’application est touchée, elle doit charger les ressources d’une instance d’objet de route appelée IndexRoute si c'est disponible. C'est pourquoi, même si aucune instance de routeur n'a été déclarée, l'application est toujours exécutée. Ember sait en interne que la route racine doit être nommée IndexRoute, va le chercher et charger ses ressources en conséquence. Dans ce cas, il crée un contrôleur qui contiendra les données à utiliser dans le modèle d'index.
Étant donné que les URL sont les identificateurs de clé utilisés par Ember pour gérer l’état de votre application, chacun aura son propre gestionnaire d’itinéraires spécifié si des ressources doivent être chargées pour cette section de l’application. Voici ce que je veux dire. supposons que vous ayez une application avec trois sections:
Dans la plupart des cas, chacune de ces sections aura ses propres ressources uniques qui doivent être chargées (par exemple: des données ou des images). Donc, vous créeriez des gestionnaires d’itinéraires en utilisant le Ressource() méthode dans l'instance d'objet de routeur d'application Ember comme ceci:
App.Router.map (function () this.resource ('accounts'); this.resource ('profiles'); this.resource ('gallery'););
Cela permet à Ember de comprendre la structure de l'application et de gérer les ressources en conséquence. Les définitions d'itinéraires seront corrélées à des instances d'objet d'itinéraire individuelles qui effectuent des tâches lourdes, telles que la configuration ou l'interfaçage de contrôleurs:
App.GalleryRoute = Ember.Route.extend (setupController: function (controller) controller.set ('content', ['pic-1.png', 'pic-2.png', 'pic-3.png' ]););
Ainsi, dans l'exemple ci-dessus, lorsqu'un utilisateur visite "/ gallery", Ember.js instancie l'objet de route GalleryRoute, configure un contrôleur avec des données et affiche le résultat. Galerie modèle. Encore une fois, c’est pourquoi les conventions de nommage sont si importantes dans Ember.
Votre application peut également avoir des URL imbriquées, telles que / compte / nouveau
Pour ces instances, vous pouvez définir des ressources Ember qui vous permettent de regrouper des itinéraires, comme suit:
App.Router.map (function () this.resource ('accounts', function () this.route ('new');););
Dans cet exemple, nous avons utilisé le Ressource()
méthode pour regrouper les itinéraires et la route()
méthode pour définir les itinéraires au sein du groupe. La règle générale est d'utiliser Ressource()
pour les noms (les comptes et les comptes sont des ressources, même lorsqu'ils sont imbriqués) et route()
pour les modificateurs: (verbes comme Nouveau
et modifier
ou des adjectifs comme favoris
et a joué
).
Outre le regroupement des itinéraires, Ember crée des références internes aux contrôleurs, itinéraires et modèles pour chacun des itinéraires de groupe spécifiés. Voici à quoi cela ressemblerait (et encore une fois cela touche les conventions de nommage d'Ember):
"/comptes":
"/ accounts / new":
Lorsqu'un utilisateur visite "/ accounts / new", un scénario de type parent / enfant ou maître / détail se produit. Ember veillera d’abord à ce que les ressources pour comptes sont disponibles et rendent le comptes modèle (c'est la partie maîtresse de celui-ci). Ensuite, il suivra et fera de même pour "/ accounts / new", en configurant les ressources et en rendant le comptes.nouveau modèle.
Notez que les ressources peuvent également être imbriquées pour des structures d'URL beaucoup plus profondes, comme ceci:
App.Router.map (function () this.resource ('accounts', function () this.route ('new'); this.resource ('pictures', function ') this.route (' add ' ););););
J'ai couvert beaucoup de matériel dans ce post. J'espère que cela a permis de simplifier certains aspects du fonctionnement d'une application Ember et du fonctionnement des itinéraires..
Nous n'avons toujours pas fini, cependant. Dans la prochaine entrée, je vais plonger dans les fonctionnalités d'Ember pour extraire des données et les rendre disponibles avec votre application. C’est là que les modèles et les contrôleurs entrent en jeu, nous allons donc nous concentrer sur la compréhension de la façon dont les deux fonctionnent ensemble.