Plonger dans CanJS Partie 2

Il s’agit de la deuxième partie d’une série en trois parties qui vous apprendra comment créer une application de gestion des contacts en JavaScript avec CanJS et jQuery. Lorsque vous aurez terminé ce didacticiel, vous aurez tout ce dont vous avez besoin pour créer vos propres applications JavaScript à l'aide de CanJS.!

Dans la première partie, vous avez créé les modèles, vues et contrôles nécessaires pour afficher les contacts et utilisé des appareils pour simuler un service REST..

Dans cette partie, vous allez:

  • Créer un contrôle et une vue pour afficher les catégories.
  • Écouter des événements à l'aide d'un contrôle.
  • Utiliser le routage pour filtrer les contacts.

Vous allez ajouter aux fichiers source de la première partie, alors si vous ne l’avez pas déjà fait, commencez par le rattraper. Je serai là quand tu seras prêt.


Configuration du routage

Le routage permet de gérer l'historique du navigateur et l'état du client dans des applications JavaScript d'une seule page..

Le routage permet de gérer l'historique du navigateur et l'état du client dans des applications JavaScript d'une seule page. Le hachage dans l'URL contient les propriétés qu'une application lit et écrit. Différentes parties de l'application peuvent écouter ces modifications et réagir en conséquence, mettant généralement à jour des parties de la page actuelle sans en charger une nouvelle..

can.route est un observable spécial qui met à jour et répond aux changements de window.location.hash. Utilisation can.route pour mapper des URL sur des propriétés, créant ainsi de jolies URL comme #! filter / all. Si aucun itinéraire n'est défini, la valeur de hachage est simplement sérialisée en notation encodée en URL, comme #! category = all.

Dans cette application, le routage sera utilisé pour filtrer les contacts par catégorie. Ajoutez le code suivant à votre contacts.js fichier:

 can.route ('filter /: category') can.route (", category: 'all')

La première ligne crée un itinéraire avec un Catégorie propriété que votre application pourra lire et écrire. La deuxième ligne crée une route par défaut, qui définit la Catégorie propriété à tout.


Travailler avec une liste d'instances modèles

UNE Model.List est un tableau observable d'instances de modèles. Lorsque vous définissez un Modèle comme Contact, une Model.List pour ce type de modèle est créé automatiquement. Nous pouvons prolonger cette création Model.List ajouter des fonctions d'assistance qui fonctionnent sur une liste d'instances de modèle.

Liste de contacts Deux fonctions d’aide seront nécessaires pour filtrer une liste de contacts et indiquer le nombre de contacts dans chaque catégorie. Ajouter ceci à contacts.js immédiatement après Contact modèle:

 Contact.List = can.Model.List (filtre: fonction (catégorie) this.attr ('longueur'); var contacts = nouveau Contact.List ([]); this.each (fonction (contact, i)  if (category === 'all' || category === contact.attr ('category')) contacts.push (contact)) renvoie les contacts;, compte: fonction (catégorie) renvoie this.filter. (catégorie) .longueur;);

Les deux fonctions d'assistance ici sont:

  • filtre() parcourt chaque contact de la liste et renvoie un nouveau Liste de contacts de contacts dans une catégorie. this.attr ('longueur') est inclus ici pour que EJS mette en place une liaison dynamique lorsque nous utiliserons cette aide dans une vue.
  • compter() renvoie le nombre de contacts dans une catégorie en utilisant le filtre() fonction d'assistance. En raison de this.attr ('longueur') dans filtre(), EJS installera la liaison en direct lorsque nous utiliserons cette aide dans une vue.

Si vous utilisez un assistant dans EJS, utilisez attr () sur une propriété de liste ou d'instance pour configurer la liaison dynamique.


Filtrage des contacts

Ensuite, vous allez modifier le contactsList.ejs afficher pour filtrer les contacts en fonction de la propriété category dans le hachage. dans le contactsList.ejs voir, modifiez le paramètre passé à la liste() aide à contacts.filter (can.route.attr ('catégorie')). Votre fichier EJS devrait ressembler à ceci lorsque vous avez terminé:

 
    <% list(contacts.filter(can.route.attr('category')), function(contact) %>
  • el.data ('contact', contact)% >>
    <%== can.view.render('contactView', contact: contact, categories: categories) %>
  • <% ) %>

En ligne deux, filtre() est appelé avec la catégorie actuelle de can.route. Depuis que tu as utilisé attr () dans filtre() et sur can.route, EJS va configurer la liaison en direct pour rendre à nouveau votre interface utilisateur lorsque l'un de ces changements.

À présent, il devrait être clair à quel point la liaison en direct est puissante. Avec un léger ajustement, l'interface utilisateur de l'application sera désormais complètement synchronisée avec non seulement la liste des contacts, mais également avec la propriété de catégorie définie dans l'itinéraire.


Affichage des catégories

Les contacts sont filtrés lorsque la propriété de catégorie du hachage est modifiée. Maintenant vous avez besoin d’un moyen de lister toutes les catégories disponibles et de changer le hash.

Commencez par créer une nouvelle vue pour afficher une liste de catégories. Enregistrez ce code sous filterView.ejs dans ton vues dossier:

 
  • Les catégories
  • Tout (<%= contacts.count('all') %>)
  • <% $.each(categories, function(i, category) %>
  • "><%= category.name %> (<%= contacts.count(category.data) %>)
  • <% ) %>

Reprenons quelques lignes de ce code et voyons ce qu’elles font:

 <% $.each(categories, function(i, category) %>

$ .each parcourt les catégories et exécute un rappel pour chacune.

 "><%= category.name %> (<%= contacts.count(category.data) %>

Chaque lien a un catégorie de données attribut qui sera tiré dans l’objet de données de jQuery. Plus tard, cette valeur peut être consultée en utilisant .données ('catégorie') sur le étiquette. Le nom de la catégorie et le nombre de contacts seront utilisés comme test de lien. La liaison en direct est configurée sur le nombre de contacts car compter() appels filtre() qui contient this.attr ('longueur').


Écouter des événements avec can.Control

Le contrôle lie automatiquement les méthodes qui ressemblent à des gestionnaires d'événements lors de la création d'une instance. La première partie du gestionnaire d'événements est le sélecteur et la deuxième partie est l'événement que vous souhaitez écouter. Le sélecteur peut être n’importe quel sélecteur CSS valide et l’événement peut être n’importe quel événement DOM ou événement personnalisé. Donc, une fonction comme 'un clic' écoutera un clic sur n'importe quel balise dans l'élément du contrôle.

Le contrôle utilise la délégation d'événements, de sorte que vous n'avez pas à vous soucier de la ré-association des gestionnaires d'événements lorsque le DOM change.


Affichage des catégories

Créez le contrôle qui gérera les catégories en ajoutant ce code à contacts.js juste après le Contacts Contrôle:

 Filter = can.Control (init: function () var category = can.route.attr ('category') || "tout"; this.element.html (can.view ('filterView', contacts: ceci .options.contacts, catégories: this.options.categories)); this.element.find ('[data-category = "' + category + '"] "). parent (). addClass (' active '); , '[catégorie de données] cliquez sur': fonction (el, ev) this.element.find ('[catégorie de données]'). parent (). removeClass ('active'); el.parent (). addClass ('active'); can.route.attr ('category', el.data ('category')););

Examinons le code du contrôle 'Filtre' que vous venez de créer:

 this.element.html (can.view ('filterView', contacts: this.options.contacts, catégories: this.options.categories));

Comme dans le Contacts Contrôle, init () les usages peut voir() rendre les catégories et html () l'insérer dans l'élément du contrôle.

 this.element.find ('[data-category = "' + categorie + '']] '). parent (). addClass (' actif ');

Trouve le lien qui correspond à la catégorie actuelle et ajoute une classe "active" à son élément parent.

 '[catégorie de données] cliquez sur': fonction (el, ev) 

Écoute un Cliquez sur événement sur tout élément correspondant au sélecteur [catégorie de données].

 this.element.find ('[catégorie de données]'). parent (). removeClass ('active'); el.parent (). addClass ('actif');

Supprime la classe 'active' de tous les liens, puis ajoute une classe 'active' au lien sur lequel l'utilisateur a cliqué..

 can.route.attr ('catégorie', el.data ('catégorie'));

Met à jour la propriété category dans can.route en utilisant la valeur de l'objet de données de jQuery pour la qui a été cliqué.


Initialiser le contrôle du filtre

Comme le Contacts Contrôle dans la première partie, vous devez créer une nouvelle instance du Filtre Contrôle. Mettez à jour votre fonction de préparation de document pour qu'elle ressemble à ceci:

 $ (document) .ready (fonction () $ .when (Category.findAll (), Contact.findAll ())). then (fonction (categoryResponse, contactResponse) var catégories = categoryResponse [0], contacts = contactResponse [0 ]; nouveaux contacts ('# contacts', contacts: contacts, catégories: catégories); nouveau filtre ('# filtre', contacts: contacts, catégories: catégories););)

Avec ce changement, une instance du Filtre Le contrôle sera créé sur le #filtre élément. Il sera passé la liste des contacts et des catégories.

Maintenant, lorsque vous exécutez votre application dans un navigateur, vous pourrez filtrer les contacts en cliquant sur les catégories à droite:


Emballer

C'est tout pour la deuxième partie! Voici ce que nous avons accompli:

  • Création d'un contrôle qui écoute les événements et gère les catégories
  • Configurer le routage pour filtrer les contacts par catégorie
  • Modifiez vos vues pour que la liaison en direct maintienne toute votre interface en phase avec votre couche de données.

Dans la troisième partie, vous mettrez à jour vos contrôles existants pour permettre aux contacts d'être modifiés et supprimés. Vous créerez également un nouveau contrôle et une vue permettant d'ajouter de nouveaux contacts..

Vous ne pouvez pas attendre pour en savoir plus? La troisième partie de la série a été publiée ici!