Bienvenue dans la troisième partie de notre série consacrée à la création d’applications à l’aide de Backbone. Si vous n'avez pas lu les parties un et deux, je vous recommande fortement de le faire - juste pour que vous sachiez où nous en sommes et ce que nous avons couvert jusqu'à présent..
Dans la première partie, nous avons pris un aperçu de base et des modèles, des vues et des collections. Dans la deuxième partie, nous avons examiné les routeurs, les événements et les modules d’historique. Dans cette partie, nous allons examiner plus en détail les interactions et voir comment ajouter ou supprimer des modèles d’une collection..
Si vous revenez à la première partie, vous vous rappellerez comment nous avons ajouté tous nos modèles à la collection lors de son initialisation. Mais comment pouvons-nous ajouter des modèles individuels à une collection après l’initialisation de la collection? C'est vraiment très facile.
Nous ajouterons la possibilité d'ajouter de nouveaux contacts, ce qui impliquera une mise à jour du code HTML sous-jacent et de notre vue principale. Tout d'abord, le HTML; ajoutez le balisage suivant au conteneur de contacts:
Ce formulaire simple permettra aux utilisateurs d'ajouter un nouveau contact. Le point principal est que le identifiant
attribut du les éléments correspondent aux noms d'attributs utilisés par nos modèles, ce qui permet d'obtenir plus facilement les données au format souhaité.
Ensuite, nous pouvons ajouter un gestionnaire d'événements à notre vue principale afin que les données du formulaire puissent être collectées. ajoutez le code suivant après la clé existante: paire de valeurs dans le événements
objet:
"click #add": "addContact"
N'oubliez pas d'ajouter la virgule de fin à la fin de la reliure existante! Cette fois nous spécifions le Cliquez sur
événement déclenché par l'élément avec un identifiant
de ajouter
, qui est le bouton sur notre formulaire. Le gestionnaire que nous lions à cet événement est ajouter le contact
, que nous pouvons ajouter ensuite. Ajoutez le code suivant après le filterByType ()
méthode de la deuxième partie:
addContact: function (e) e.preventDefault (); var newModel = ; $ ("# addContact"). enfants ("entrée"). each (fonction (i, el) if ($ (el) .val ()! == "") newModel [el.id] = $ ( el) .val ();); contacts.push (formData); if (_.indexOf (this.getTypes (), formData.type) === -1) this.collection.add (nouveau contact (formData)); this. $ el.find ("# filtre"). find ("select"). remove (). end (). append (this.createSelect ()); else this.collection.add (nouveau contact (formData));
Comme il s’agit d’un gestionnaire d’événements, il recevra automatiquement le message. un événement
objet, que nous pouvons utiliser pour empêcher le comportement par défaut du élément quand il est cliqué (qui serait de soumettre le formulaire et recharger la page - pas ce que nous voulons). Nous créons ensuite un nouvel objet vide et utilisons jQuery
chaque()
méthode pour parcourir chaque élément de notre
ajouter le contact
forme.
Dans la fonction de rappel fournie à chaque()
, nous vérifions d'abord que du texte a été entré dans le champ et, le cas échéant, nous ajoutons une nouvelle propriété à l'objet avec une clé égale à identifiant
de l'élément en cours, et une valeur égale à sa valeur en cours valeur
. Si le champ est vide, la propriété ne sera pas définie et le nouveau modèle héritera des valeurs par défaut éventuellement spécifiées..
Ensuite, nous pouvons mettre à jour notre magasin de données local avec le nouveau contact. C’est là que nous enregistrerions probablement les nouvelles données sur le serveur - si nous avions un serveur en place pour recevoir de telles demandes. À ce stade, nous ne le faisons pas. Nous allons donc simplement mettre à jour le tableau d'origine pour que, si la vue est filtrée, les nouvelles données ne soient pas perdues. Il ne reste plus qu'à utiliser la collection ajouter()
méthode pour ajouter les nouvelles données à la collection. Nous pouvons créer le nouveau modèle à transmettre à la collection lors de l'appel à ajouter()
.
Enfin, nous devons mettre à jour le élément de sorte que si le nouveau contact a un type différent, ce type est disponible pour le filtrage. Cependant, nous voulons seulement redonner le rendu
si un nouveau type a été ajouté. Nous pouvons utiliser Underscore
Indice de()
méthode de recherche dans un tableau pour une valeur particulière. J'aime le JavaScript natif Indice de()
méthode pour les chaînes, cette méthode retournera -1
si la valeur n'est pas trouvée. Nous passons le tableau à rechercher comme premier argument de Indice de()
, et la valeur à rechercher en tant que deuxième.
Si la valeur n’est pas trouvée, le type spécifié doit être nouveau afin que nous trouvions la zone de sélection existante et la supprimions avant d’en ajouter une nouvelle générée par notre createSelect ()
méthode. Si le type est trouvé, nous pouvons simplement ajouter le nouveau modèle sans avoir à retransformer le select.
Maintenant que nous avons ajouté un nouveau modèle à la collection, nous devrions le restituer sur la page. Pour ce faire, nous pouvons lier un autre gestionnaire, cette fois pour écouter le ajouter
un événement. Ajoutez la ligne de code suivante au initialiser()
méthode de collecte:
this.collection.on ("add", this.renderContact, this);
Nous utilisons le sur()
méthode une fois de plus pour attacher l'écouteur d'événement et comme nous avons déjà une méthode qui crée et affiche des vues individuelles, nous spécifions simplement cette fonction en tant que gestionnaire. Nous avons également défini la vue principale comme objet this dans le gestionnaire, comme nous l’avions fait avec les gestionnaires précédents. À ce stade, nous devrions maintenant être en mesure de remplir le formulaire et de renvoyer le nouveau contact sur la page:
Une chose à noter est que si le ajouter le contact
les champs de formulaire sont laissés complètement vides, le modèle résultant sera presque entièrement dépourvu d'attributs, ce qui posera des problèmes lorsque nous tenterons de manipuler le modèle ultérieurement. Une façon d’éviter cela est de fournir des valeurs par défaut pour la majorité des attributs de modèle, tout comme nous avons fourni la valeur par défaut. photo
attribut. S'il n'y a pas de valeurs par défaut raisonnables que nous pouvons utiliser, comme pour le nom d'un contact par exemple, nous pouvons simplement fournir une chaîne vide. Mettre à jour le défauts
objet dans le Contact
classe pour inclure les valeurs par défaut pour nos autres attributs:
nom: "", adresse: "", tel: "", email: "", type: ""
Maintenant que nous savons comment ajouter des modèles à la collection, nous devons également examiner comment les supprimer. Une façon de permettre la suppression de modèles individuels consiste à ajouter un bouton de suppression à chaque contact. C'est ce que nous allons faire. Nous devons d’abord mettre à jour le modèle pour chaque vue afin qu’il contienne un bouton de suppression. Ajouter un nouveau bouton à la fin du modèle:
C'est tout ce dont nous avons besoin pour cet exemple. La logique permettant de supprimer un modèle individuel peut être ajoutée à la classe de vue qui représente un contact individuel, car l'instance de vue sera associée à une instance de modèle particulière. Nous devrons ajouter une liaison d'événement et un gestionnaire d'événements pour supprimer le modèle lorsque l'utilisateur clique sur le bouton. ajoutez le code suivant à la fin de la ContactVue
classe:
events: "click button.delete": "deleteContact", deleteContact: function () var removeType = this.model.get ("type"). toLowerCase (); this.model.destroy (); this.remove (); if (_.indexOf (directory.getTypes (), removedType) === -1) répertoire. $ el.find ("# filtre select"). children ("[valeur = '" + supprimeType + "']" ).retirer();
Nous utilisons le événements
object pour spécifier notre liaison d’événement, comme nous l’avions fait auparavant avec notre vue principale. Cette fois, nous écoutons Cliquez sur
événements déclenchés par un qui a le nom de la classe
effacer
. Le gestionnaire lié à cet événement est supprimer le contact
, que nous ajoutons après la événements
objet.
Nous enregistrons d’abord le type du contact que nous venons de supprimer. Nous devons définir cette valeur en minuscule, comme auparavant, pour éviter tout problème lors de l'utilisation du visualiseur de contacts..
Nous appelons ensuite le détruire()
méthode sur le modèle associé à ce
, l'instance de la vue. Nous pouvons également supprimer la représentation HTML de la vue de la page en appelant jQuery retirer()
méthode, qui a l'avantage supplémentaire de nettoyer tous les gestionnaires d'événements attachés à la vue.
Enfin, nous obtenons tous les types de modèles dans la collection de répertoires et vérifions si le type du contact qui vient d'être supprimé est toujours contenu dans le tableau résultant. Si ce n’est pas le cas, il n’ya plus de contacts de ce type et nous devrions donc supprimer cette option de la sélection..
Nous sélectionnons l’élément à supprimer en recherchant d’abord la zone de sélection, puis en utilisant un sélecteur d’attributs pour sélectionner avec un attribut de valeur qui correspond à la
removeType
variable que nous avons enregistré au début de la méthode. Si nous supprimons tous les contacts d’un certain type, puis vérifions la élément, nous devrions trouver que le type n'est plus dans la liste déroulante:
Ok, ce sous-titre est un peu trompeur; ce que je veux dire, c'est qu'en plus de supprimer le modèle et la vue, nous devrions également supprimer les données d'origine de notre tableau de contacts à partir desquelles le modèle a été construit. Si nous ne le faisons pas, le modèle qui a été supprimé reviendra à chaque fois qu'il est filtré. Dans une application réelle, c’est probablement là que nous synchroniserions avec un serveur afin de conserver les données..
La fonctionnalité permettant de supprimer l'élément du tableau d'origine peut résider dans notre vue principale. la collection va tirer un retirer
événement lorsque l'un des modèles est supprimé de la collection, nous pouvons donc simplement lier un gestionnaire pour cet événement à la collection dans la vue principale. Ajoutez la ligne de code suivante directement après les liaisons existantes:
this.collection.on ("remove", this.removeContact, this);
Vous devriez déjà être au courant de cette déclaration, mais pour rappel, le premier argument de la sur()
method est l'événement que nous écoutons, le second est le gestionnaire à exécuter lorsque l'événement se produit et le troisième est le contexte à utiliser de la sorte lorsque le gestionnaire est exécuté. Ensuite, nous pouvons ajouter le supprimer contact()
méthode; après le ajouter le contact()
méthode ajouter le code suivant:
removeContact: function (removedModel) var remove = removeModel.attributes; if (removed.photo === "/img/placeholder.png") delete removed.photo; _.each (contacts, fonction (contact) if (_. isEqual (contact, supprimé)) contacts.splice (_. indexOf (contacts, contact), 1););
Backbone transmet utilement à notre gestionnaire le modèle qui vient d'être supprimé de la collection. Nous stockons une référence à la collection d'attributs afin de pouvoir comparer le modèle supprimé avec les éléments de notre tableau de contacts d'origine. La propriété photo n'a pas été définie pour les éléments d'origine du tableau de contacts, mais comme cette propriété est spécifiée comme propriété par défaut, tous nos modèles hériteront de la propriété et échoueront par conséquent toute comparaison avec les objets du tableau de contacts..
Dans cet exemple, nous devons vérifier si le photo
propriété du modèle est la même que la valeur par défaut, et si c'est le cas, nous supprimons le photo
propriété.
Ceci fait, nous pouvons parcourir chaque élément de la liste. Contacts
array et testez-le pour voir s'il est identique au modèle supprimé de la collection. Nous pouvons comparer chaque élément avec l'objet que nous stockons dans la variable supprimée à l'aide de Underscore est égal()
méthode.
Si la est égal()
méthode renvoie true, nous appelons alors le JavaScript natif épissure()
méthode sur le Contacts
tableau, en passant l’index de l’élément à supprimer et le nombre d’éléments à supprimer. L'indice est obtenu en utilisant le trait de soulignement Indice de()
méthode que nous avons utilisée plus tôt.
Désormais, lorsqu'un bouton de suppression est cliqué, la vue, le modèle et les données d'origine seront supprimés. Nous pouvons également filtrer la vue, puis revenir à la vue de tous les contacts, et le contact qui a été supprimé ne sera toujours pas affiché.
Nous avons donc un peu abandonné le ajouter le contact
forme sur la page il n'y a pas nous? Pour clore cette partie du didacticiel, nous pouvons faire quelque chose pour le garder caché jusqu'à ce qu'un lien soit cliqué. Nous pouvons ajouter le lien suivant au élément:
Ajouter un nouveau contact
Pour que le lien affiche le formulaire, nous devons d'abord le masquer, puis utiliser un gestionnaire d'événements UI pour l'afficher. La liaison peut être ajoutée à la événements
objet dans le DirectoryView
classe:
"cliquez sur #showForm": "showForm"
Notre showForm ()
La méthode peut être aussi simple que la suivante (bien que vous souhaitiez probablement en faire un peu plus que ce que nous faisons ici!):
showForm: function () this. $ el.find ("# addContact"). slideToggle ();
Dans ce didacticiel, nous avons uniquement examiné la manière dont de nouveaux modèles peuvent être ajoutés à une collection et comment les modèles peuvent être supprimés d'une collection. Nous avons vu que les méthodes Backbone utilisées pour ajouter et supprimer des modèles sont, sans surprise, les ajouter()
et retirer()
les méthodes.
Nous avons également vu comment lier les gestionnaires aux événements déclenchés automatiquement lorsque ces méthodes sont utilisées afin de mettre à jour l'interface utilisateur et la collection, si nécessaire..
Nous avons également examiné certaines fonctions utilitaires Underscore plus utiles que nous pouvons utiliser pour exploiter nos données, notamment: _Indice de()
qui retourne l'index d'un élément dans un tableau, et est égal()
qui peut être utilisé pour comparer en profondeur deux objets pour voir s'ils sont identiques.
Comme dans la dernière partie de ce tutoriel, nous avons également vu comment écrire nos classes de telle sorte que leurs fonctionnalités puissent être partagées et réutilisées chaque fois que cela est possible. Lorsque nous avons ajouté un nouveau modèle, par exemple, nous avons utilisé le modèle existant. renderContact ()
méthode définie dans notre DirectoryView
classe pour gérer le rendu du code HTML pour le nouveau contact.
Nous avons donc vu comment ajouter des modèles et les supprimer, rejoignez-moi dans la prochaine partie de cette série, où nous verrons comment modifier les données de modèles existants..