Entrer dans la braise Partie 4

Dans mon précédent tutoriel, j'ai abordé comment utiliser Ember.Object pour définir vos modèles et travailler avec des jeux de données. Dans cette section, nous verrons plus en détail comment Ember utilise le framework de templates Handlebars pour définir l'interface utilisateur de votre application..


Modèles côté client

La plupart des développeurs côté serveur sont habitués à utiliser des modèles pour définir un balisage qui sera rempli dynamiquement à la volée. Si vous avez déjà utilisé ASP.NET, ColdFusion, PHP ou Rails, il est pratiquement certain que vous savez de quoi je parle.

JavaScript La modélisation côté client a vraiment pris son envol ces derniers temps, en particulier en raison de l’accent mis sur la création d’expériences de type poste de travail. Cela signifie que davantage de traitements sont effectués côté client, les données étant principalement extraites via des requêtes d'API côté serveur..

Je me souviens d'avoir écrit sur les modèles côté client il y a quelque temps, lorsque le plug-in jQuery Template a été publié. Près de trois ans plus tard, c'est toujours l'article le plus lu sur mon blog, qui montre à quel point l'intérêt pour les modèles côté client a augmenté. Depuis lors, plusieurs autres cadres ont été publiés, offrant des fonctionnalités riches et des communautés de soutien. Le guidon est l’une des options les plus populaires et le cadre choisi par le projet Ember pour répondre à ses besoins en matière de modèles. Cela fait sens puisque Handlerbars a été créé par le co-fondateur et membre de l’équipe principale d’Ember.js, Yehuda Katz. Notez cependant que je n'ai pas l'intention de faire des comparaisons entre les frameworks de templates et que je vais me concentrer strictement sur Handelbars puisque c'est ce que Ember.js utilise par défaut.

Dans les articles précédents, j'ai montré quelques modèles très basiques dans le code:

 

La déclaration de type de la balise script et les accolades qui délimitent les expressions sur lesquelles Handlebars agira sont deux éléments qui se démarquent. C’est une syntaxe très typique dont je parlerai plus en détail prochainement et que vous utiliserez de manière cohérente lors de la création de modèles Ember..


La syntaxe

En dépit du fait que Handlebars utilise une syntaxe spéciale, en fin de compte, vous travaillez principalement avec du balisage HTML standard. Les guidons servent à injecter du contenu dans ce balisage pour restituer les données à l'utilisateur. Pour ce faire, il analyse les expressions délimitées et les remplace par les données que vous avez demandé au guidon de manipuler. Dans le cas de Ember, Handlebars fournit les crochets et Ember les utilise. Ces données proviennent généralement de votre contrôleur (n'oubliez pas que les contrôleurs servent d'interface avec vos modèles).

La première chose dont tout modèle a besoin est une définition de balise de script. La plupart d'entre vous ont probablement défini des balises de script pour charger votre bibliothèque JavaScript. En fait, vous avez déjà fait cela pour charger des guidons dans votre projet Ember:

    

Il y a une légère différence avec son utilisation pour définir un modèle. Tout d'abord, nous spécifions un type attribut de "text / x-handlebars". Ce type est ignoré par le navigateur mais laisse le texte disponible pour l'inspection et permet à Ember d'identifier les modèles dans l'application. En outre, Ember utilise un attribut de données appelé "nom de modèle de données", qu'il peut utiliser pour associer des parties spécifiques de votre application à un modèle. Par exemple, la déclaration suivante définit un modèle avec le nom "employee":

 

Au démarrage de votre application, Ember analyse le DOM à la recherche de type = "text / x-guidon, compile les modèles qu’il trouve et les stocke dans une propriété de l’objet Ember, appelée Ember.TEMPLATES qu’il utilise pour déterminer ce qu’il faut rendre pour un itinéraire donné. C'est pourquoi il est si important de respecter les conventions de dénomination d'Ember. Dans l'exemple ci-dessus, ce modèle sera automatiquement associé à la route des employés et au contrôleur créés dans votre application. Encore une fois, je ne saurais trop insister sur le fait que ces conventions de dénomination faciliteront grandement votre développement..

Ember s'appuie sur les URL pour déterminer les ressources à utiliser et les modèles à restituer. Imaginons que vous ayez une page de profil avec l'URL "/ profile". Vous auriez une ressource, appelée profil cela chargerait des ressources spécifiques pour cette URL (comme un objet route) et vous auriez également un modèle du même nom. Nous avons examiné la définition des ressources et des objets route dans la partie 2 de ma série Ember. Par conséquent, si vous n'êtes pas sûr de ce dont je parle, veillez à vous y rendre pour vous rafraîchir la mémoire..

Lorsque vous visitez cette URL, Ember sait qu'il doit charger ces ressources et analyser le modèle que vous avez défini. Il le fait via ses conventions de nommage, sachant que parce que vous êtes allé à "/ profile", il doit charger les ressources définies dans le fichier. profil, et restituer le modèle nommé data-template-name = "profil".

  • Route: ProfileRoute
  • Manette: ProfileController
  • Modèle: profil (notez qu'il est en minuscule)

Si vous revenez sur les conventions de dénomination, vous verrez que la route, le contrôleur et le modèle sont tous liés en utilisant le même nom d’URL, à la différence près que le modèle est orthographié en minuscule. C’est ce qui permet à Ember de gérer tout ce qui se passe dans les coulisses sans avoir à effectuer beaucoup de câblage..

Il est également important de noter que si vous déclarez un modèle sans nom de modèle de données attribut, Ember supposera qu'il s'agit du modèle à portée d'application, généralement utilisé comme modèle à l'échelle du site pour la création d'éléments d'interface utilisateur, tels que les en-têtes, les pieds de page et la navigation. Et si vous ne définissez pas explicitement un modèle pour une application ou même une ressource (par exemple, pour une URL), Ember le fait automatiquement pour vous assurer la stabilité et la cohérence de votre application..


Expressions

L'étape suivante consiste à inclure votre balise et les expressions délimitées que vous utiliserez pour représenter vos données. Les expressions sont délimitées par des doubles accolades qui leur permettent d'être facilement identifiées et analysées avec les données transmises par votre contrôleur. Voici un exemple:

 

Dans ce cas, le Prénom et nom de famille les expressions seront analysées par Ember et remplacées par les données réelles. De plus, Ember configure des observateurs pour que, à mesure que vos données changent, votre modèle soit automatiquement mis à jour et que les mises à jour soient reflétées pour l'utilisateur de votre application..

Jusqu'ici, je vous ai montré un exemple très simple, mais la conclusion est que:

  • Ember utilise un attribut de type spécial pour définir les modèles.
  • Les modèles utilisent un balisage standard avec des expressions délimitées, qui sont analysées côté client..
  • Ces modèles offrent toutes les fonctionnalités du guidon..
  • Ember configure des observateurs pour mettre à jour dynamiquement les données de votre interface utilisateur à mesure qu'elles évoluent..

Cela offre beaucoup de flexibilité dans la structure de votre interface utilisateur. Continuons à regarder les fonctionnalités disponibles.


Expressions avancées

N'oubliez pas qu'Ember utilise le guidon pour vous permettre d'accéder à toute la gamme de ses expressions ici. Les expressions conditionnelles sont indispensables pour rendre presque n'importe quoi utile; Le guidon offre de nombreuses options.

Disons que j'ai un jeu de données JSON qui ressemble à ceci:

 "items": ["title": "Simulation de tissu déchirable en JavaScript", "url": "http://codepen.io/stuffit/pen/KrAwx", "id": 5592679, "commentCount": 20, "points": 127, "postedAgo": "Il y a 1 heure", "postedBy": "NathanKP", "title": "Netflix désormais plus grand que HBO", "url": "http://qz.com / 77067 / netflix-now-larger-than-hbo / "," id ": 5592403," commentCount ": 68," points ": 96," postedAgo ":" il y a 2 heures "," postedBy ":" edouard1234567 " 

Si je voulais m'assurer que le Titre données sont disponibles, je pourrais ajouter une instruction conditionnelle "if" en utilisant le #si expression:

 #if item.title 
  • item.title - item.postedAgo par item.postedBy
  • /si

    Ceci vérifie si item.title n'est pas indéfini et continue à traiter les expressions suivantes pour le Titre, postéAgo et posté par expressions de données.

    Étant donné que cet ensemble de données contient plusieurs "enregistrements", il est prudent de supposer que nous voudrions probablement passer en boucle sur chaque élément de article. C'est là que le #chaque l'expression entre en jeu. Il vous permet d'énumérer une liste d'objets. Donc, encore une fois, en gardant à l’esprit que les modèles sont une combinaison des expressions de balisage et de Guidon, nous pouvons utiliser le #chaque expression pour parcourir tous les éléments disponibles dans notre objet modèle Ember. Rappelez-vous que le modèle Ember est dérivé du contrôleur associé au modèle via les conventions de nommage d'Ember..

     
      #chaque article dans le modèle #if item.title
    • item.title - item.postedAgo par item.postedBy
    • / if / each

    Cela rendrait quelque chose de similaire à:

     
    • Tearable Cloth Simulation in JavaScript - Il y a 1 heure par NathanKP
    • Netflix maintenant plus grand que HBO - Il y a 2 heures par edouard1234567
    • Une base de données rapide émerge de la classe MIT, des GPU et de l'invention des étudiants - Il y a 33 minutes par signa11
    • Connexion d'un iPad LCD rétine à un PC - Il y a 6 heures par noonespecial

    L’avantage est la spécification implicite d’observateurs d’Ember qui met à jour vos données lors d’une mise à jour..

    Si votre expression conditionnelle doit être plus complexe, vous souhaiterez créer une propriété calculée. Cela vous permet de créer une propriété basée sur une méthode pouvant appliquer des conditions de code complexes à vos données. Supposons que je veuille uniquement afficher des données portant le titre "Simulation de tissu déchirable en JavaScript". Il y a quelques choses que je dois configurer:

    • J'ai besoin d'une propriété calculée pour analyser chaque élément et me dire si le titre correspond
    • Je dois créer un contrôleur pouvant être utilisé par chaque élément énuméré dans le modèle.
    • J'ai besoin de mettre à jour le modèle pour qu'il utilise ce contrôleur pour chaque élément
      La première chose à faire est de créer le nouveau contrôleur qui encapsulera chaque élément à boucler et créera la propriété calculée en son sein:
     App.TitleController = Ember.ObjectController.extend (titleMatch: function () return this.get ('title') === "Simulation de tissu déchirable en JavaScript"; .property ());

    En regardant le code, nous sous-classons Ember.ObjectController pour créer le contrôleur. C'est le contrôleur qui encapsulera chaque élément en boucle dans notre modèle. Ensuite, nous créons une méthode, appelée titleMatch qui utilise le obtenir() méthode pour extraire le titre actuel, le comparer au texte que j'ai défini et renvoyer un booléen. Enfin, la braise propriété() la méthode est appelée pour définir la titleMatch méthode en tant que propriété calculée.

    Une fois que nous avons cela en place, nous mettons à jour le modèle #chaque expression pour représenter chaque élément avec le nouveau contrôleur que nous avons créé. Ceci est fait en utilisant le itemController directif. Un élément clé à comprendre est que itemController est une phrase clé dans Ember destinée à associer un contrôleur à des éléments d’un modèle. Ne confondez pas cela pour un nom de contrôleur réel (comme je l'avais initialement). Le nom du contrôleur est attribué à itemController, comme ça:

     
      #chaque article dans le modèle itemController = "title" #if titleMatch
    • foo.title - foo.postedAgo par foo.postedBy
    • / if / each

    Encore une fois, les conventions de dénomination dictent que, lors de l'attribution de noms dans des modèles, nous utilisons des minuscules. Dans ce cas, nous assignons TitleController à itemController.

    Maintenant, comme chaque élément est bouclé, la propriété calculée, titleMatch, est utilisé pour évaluer le titre et afficher les données si elles correspondent.


    Liaison de données à des éléments

    Créer des modèles dynamiques ne consiste pas seulement à cracher du texte. Il arrive que l'apparence de l'interface utilisateur soit affectée par le traitement des données. L'affichage d'une image ou la création d'un lien en sont d'excellents exemples..

    Pour lier des données à un élément, il est nécessaire d'utiliser des assistants Ember spéciaux qui aident à définir le contexte d'un attribut et garantissent que les attributs sont mis à jour correctement lorsque les données changent. Pour les attributs d'élément, le bindAttr helper est utilisé pour renseigner les valeurs d'un attribut. Si nous devions spécifier dynamiquement l'URL d'une image, nous utiliserions la syntaxe suivante:

     Logo

    La même chose peut être faite pour les attributs qui ne reçoivent pas de valeur, tels que désactivée:

     

    Dans ce cas, isAdminstrator Il peut s'agir d'une propriété calculée basée sur une méthode du contrôleur ou simplement d'une propriété d'objet normale, ce qui vous donne beaucoup de flexibilité pour définir les conditions de désactivation de la case à cocher. Cette flexibilité se répercute également sur la définition des noms de classe. Si je voulais utiliser une instruction conditionnelle pour définir si une classe devait être appliquée à mon élément, je pourrais utiliser le code suivant:

     
    Attention!

    En fonction de l'état booléen, mon balisage serait soit:

     
    Attention!

    pour un vrai condition, ou:

     
    Attention!

    pour un faux état. Notez que, quand j'ai spécifié estUrgent pour la classe, Ember a dasherisé le nom et a rendu la classe comme est urgent. Si vous préférez spécifier votre propre classe en fonction des résultats, vous pouvez utiliser une expression conditionnelle semblable à une instruction ternaire:

     

    Cela va retourner urgent ou Ordinaire pour la classe, en fonction de la valeur conditionnelle de estUrgent.


    Connaître les modèles

    Les modèles constitueront la base de votre interface utilisateur. Il est donc important que vous preniez le temps de lire les documents sur les sites Ember et Handlebars pour avoir une idée précise de leur puissance globale. Même si vous n'utilisez pas Ember, Handlebars constitue un excellent cadre de travail quotidien et vaut la peine d'investir pour apprendre à l'utiliser..

    Gabriel Manricks a écrit un excellent tutoriel sur le guidon ici sur Nettuts + que vous pouvez utiliser pour vous familiariser avec le cadre..