Benvenuti alla terza parte della nostra serie che si concentra sulla creazione di applicazioni utilizzando Backbone. Se non hai letto le parti 1 e 2, ti consiglio vivamente di farlo - solo così sai dove siamo e cosa abbiamo trattato finora.
Nella prima parte, abbiamo preso un aspetto e modelli di base, viste e collezioni. Nella seconda parte, abbiamo esaminato i router, gli eventi e i moduli della storia. In questa parte, esamineremo ulteriormente le interazioni e vediamo come aggiungere o rimuovere modelli da una raccolta.
Se ripensi la tua mente alla prima parte, ti ricorderai come abbiamo aggiunto tutti i nostri modelli alla collezione quando la collezione è stata inizializzata. Ma come possiamo aggiungere singoli modelli a una collezione dopo che la collezione è già stata inizializzata? In realtà è davvero facile.
Aggiungeremo la possibilità di aggiungere nuovi contatti che comporteranno un aggiornamento dell'HTML sottostante e della nostra vista principale. Innanzitutto, l'HTML; aggiungi il seguente mark-up al contenitore dei contatti:
Questo semplice modulo consentirà agli utenti di aggiungere un nuovo contatto. Il punto principale è che il id
attributore del gli elementi corrispondono ai nomi degli attributi utilizzati dai nostri modelli, il che rende più facile ottenere i dati nel formato che vogliamo.
Successivamente, possiamo aggiungere un gestore di eventi alla nostra vista principale in modo che i dati nel modulo possano essere raccolti; aggiungere il seguente codice dopo la chiave esistente: coppia di valori nel file eventi
oggetto:
"fai clic su #add": "addContact"
Non dimenticare di aggiungere la virgola finale alla fine del bind esistente! Questa volta specifichiamo il clic
evento innescato dall'elemento con un id
di Inserisci
, che è il pulsante sul nostro modulo. Il gestore che stiamo vincolando a questo evento è Agg.contatto
, che possiamo aggiungere in seguito. Aggiungere il seguente codice dopo il filterByType ()
metodo dalla seconda parte:
addContact: function (e) e.preventDefault (); var newModel = ; $ ("# addContact"). children ("input"). each (function (i, el) if ($ (el) .val ()! == "") newModel [el.id] = $ ( el) .val ();); contacts.push (formdata); if (_.indexOf (this.getTypes (), formData.type) === -1) this.collection.add (new Contact (formData)); questo $ el.find ( "# filtro") trovare ( "select") rimuovere () end () aggiungere (this.createSelect ()).....; else this.collection.add (new Contact (formData));
Poiché questo è un gestore di eventi, riceverà automaticamente il evento
oggetto, che possiamo usare per prevenire il comportamento predefinito di elemento quando viene cliccato (che sarebbe quello di inviare il modulo e ricaricare la pagina - non quello che vogliamo). Creiamo quindi un nuovo oggetto vuoto e usiamo jQuery
ogni()
metodo per iterare su ciascuno elemento nel nostro
Agg.contatto
modulo.
Nella funzione di callback fornita a ogni()
, per prima cosa controlliamo che il campo abbia inserito del testo e, in tal caso, aggiungiamo una nuova proprietà all'oggetto con una chiave uguale alla id
dell'elemento corrente e un valore uguale alla sua corrente valore
. Se il campo è vuoto, la proprietà non verrà impostata e il nuovo modello erediterà eventuali valori predefiniti che potrebbero essere stati specificati.
Successivamente, possiamo aggiornare il nostro archivio dati locale con il nuovo contatto. È qui che probabilmente salveremmo i nuovi dati sul server - se avessimo un server sul posto per ricevere tali richieste. A questo punto non lo facciamo, quindi aggiorneremo l'array originale per ora in modo che se la vista viene filtrata, i nuovi dati non vadano persi. Tutto quello che dobbiamo fare è usare la collezione Inserisci()
metodo per aggiungere i nuovi dati alla raccolta. Possiamo creare il nuovo modello da inserire nella raccolta all'interno della chiamata a Inserisci()
.
Infine, dobbiamo aggiornare il elemento in modo che se il nuovo contatto ha un tipo diverso, quel tipo è disponibile per il filtro. Tuttavia, vogliamo solo ri-renderizzare il
se è stato aggiunto un nuovo tipo. Possiamo usare Underscore's
indice di()
metodo per cercare attraverso una matrice per un valore particolare. Come il codice JavaScript nativo indice di()
metodo per le stringhe, questo metodo tornerà -1
se il valore non è stato trovato. Passiamo la matrice alla ricerca come primo argomento indice di()
, e il valore da cercare come secondo.
Se il valore non viene trovato, il tipo specificato deve essere nuovo, quindi troviamo la casella di selezione esistente e rimuoverla prima di aggiungerne una nuova generata dal nostro createSelect ()
metodo. Se il tipo viene trovato, possiamo semplicemente aggiungere il nuovo modello senza dover ri-renderizzare la selezione.
Ora che abbiamo aggiunto un nuovo modello alla raccolta, dovremmo renderlo sulla pagina. Per fare questo possiamo legare un altro gestore, questa volta per ascoltare il Inserisci
evento. Aggiungi la seguente riga di codice al inizializzare()
metodo della raccolta:
this.collection.on ("aggiungi", this.renderContact, this);
Noi usiamo il sopra()
metodo ancora una volta per collegare il listener di eventi e poiché abbiamo già un metodo che crea e visualizza singole visualizzazioni, dobbiamo solo specificare quella funzione come gestore. Abbiamo anche impostato la vista principale come questo oggetto all'interno del gestore come abbiamo fatto con i gestori precedenti. A questo punto, ora dovremmo essere in grado di completare il modulo e avere il nuovo contatto reso alla pagina:
Una cosa da notare è che se il Agg.contatto
i campi modulo vengono lasciati completamente vuoti, il modello risultante sarà quasi interamente privo di attributi, il che causerà problemi quando tenteremo di manipolare il modello in un secondo momento. Un modo per evitare questo è fornire valori predefiniti per la maggior parte degli attributi del modello, proprio come abbiamo fornito l'impostazione predefinita foto
attributo. Se non ci sono impostazioni predefinite sensibili che possiamo usare, ad esempio per il nome di un contatto, possiamo solo fornire una stringa vuota. Aggiorna il default
oggetto nel Contatto
classe per includere i valori predefiniti per gli altri nostri attributi:
nome: "", indirizzo: "", tel: "", email: "", digitare: ""
Ora che sappiamo come aggiungere modelli alla collezione, dovremmo esaminare come possono essere rimossi. Un modo in cui possiamo abilitare l'eliminazione dei singoli modelli è aggiungendo un pulsante Elimina a ciascun contatto, quindi questo è ciò che faremo; per prima cosa dobbiamo aggiornare il modello per ogni singola vista in modo che contenga un pulsante di cancellazione. Aggiungi un nuovo pulsante alla fine del modello:
Questo è tutto ciò di cui abbiamo bisogno per questo esempio. La logica per rimuovere un singolo modello può essere aggiunta alla classe vista che rappresenta un singolo contatto, poiché l'istanza della vista sarà associata a una particolare istanza del modello. Dovremo aggiungere un binding di eventi e un gestore di eventi per rimuovere il modello quando si fa clic sul pulsante; aggiungi il seguente codice alla fine del ContactView
classe:
eventi: "click button.delete": "deleteContact", deleteContact: function () var removedType = this.model.get ("type"). toLowerCase (); this.model.destroy (); this.remove (); if (_.indexOf (directory.getTypes (), removedType) === -1) directory. $ el.find ("# filter select"). children ("[valore = '" + removedType + "']" ).rimuovere();
Noi usiamo il eventi
oggetto di specificare il nostro binding di eventi, come abbiamo fatto prima con la nostra vista principale. Questa volta stiamo ascoltando clic
eventi innescati da a questo ha il nome della classe
Elimina
. Il gestore associato a questo evento è deleteContact
, che aggiungiamo dopo il eventi
oggetto.
Per prima cosa memorizziamo il tipo di contatto che abbiamo appena cancellato. Dovremmo rendere questo valore in minuscolo come fatto prima per garantire che non ci siano problemi di maiuscole o minuscole quando il visualizzatore di contatti è in uso.
Quindi chiamiamo il distruggere()
metodo sul modello associato a Questo
, l'istanza della vista. Possiamo anche rimuovere la rappresentazione HTML della vista dalla pagina chiamando jQuery rimuovere()
metodo, che ha il vantaggio di ripulire eventuali gestori di eventi collegati alla vista.
Alla fine, otteniamo tutti i tipi di modelli nella collezione di directory e controlliamo se il tipo di contatto che è stato appena rimosso è ancora contenuto nell'array risultante. Se non lo è, non ci sono più contatti di quel tipo e dovremmo quindi rimuovere quell'opzione dalla selezione.
Selezioniamo l'elemento da rimuovere trovando prima la casella di selezione, quindi utilizzando un selettore di attributo per selezionare il con un attributo value che corrisponde a
removedType
variabile che abbiamo salvato all'inizio del metodo. Se rimuoviamo tutti i contatti di un certo tipo e quindi controlliamo il elemento, dovremmo trovare che il tipo non è più nel menu a discesa:
Ok, questo sottotitolo è un po 'fuorviante; quello che intendo è che oltre a rimuovere il modello e la vista, dovremmo anche rimuovere i dati originali nel nostro array di contatti dal quale il modello è stato originariamente creato. Se non lo facciamo, il modello che è stato rimosso tornerà ogni volta che viene filtrato. In un'applicazione reale, questo è probabilmente il punto in cui dovremmo eseguire la sincronizzazione con un server per mantenere i dati.
La funzionalità per rimuovere l'elemento dall'array originale può risiedere all'interno della nostra vista principale; la collezione licenzierà a rimuovere
evento quando uno dei modelli viene rimosso dalla raccolta, quindi possiamo semplicemente associare un gestore per questo evento alla raccolta nella vista principale. Aggiungi la seguente riga di codice direttamente dopo i bind esistenti:
this.collection.on ("remove", this.removeContact, this);
Dovresti essere abbastanza familiare con questa affermazione ormai, ma come promemoria, il primo argomento del sopra()
metodo è l'evento che stiamo ascoltando, il secondo è il gestore da eseguire quando si verifica l'evento, e il terzo è il contesto da utilizzare come questo quando viene eseguito il gestore. Successivamente possiamo aggiungere il Rimuovi il contatto()
metodo; dopo il Agg.contatto ()
metodo aggiungi il seguente codice:
removeContact: function (removedModel) var removed = removedModel.attributes; if (removed.photo === "/img/placeholder.png") delete removed.photo; _.each (contatti, funzione (contatto) if (_.isEqual (contatto, rimosso)) contacts.splice (_. indexOf (contatti, contatto), 1););
Backbone passa utilmente al nostro gestore il modello che è appena stato rimosso dalla collezione. Archiviamo un riferimento alla collezione di attributi in modo da poter confrontare il modello che è stato rimosso con gli elementi nella nostra matrice di contatti originale. Gli elementi originali nell'array di contatti non avevano la proprietà foto definita, ma poiché questa è specificata come proprietà predefinita, tutti i nostri modelli erediteranno la proprietà e quindi non avranno alcun confronto con gli oggetti nell'array di contatti.
In questo esempio, dobbiamo verificare se il foto
la proprietà del modello è uguale al valore predefinito e, in caso affermativo, rimuoveremo foto
proprietà.
Una volta che questo è fatto, possiamo scorrere su ogni oggetto nel contatti
array e testarlo per vedere se è uguale al modello che è stato rimosso dalla collezione. Possiamo confrontare ciascun elemento con l'oggetto che memorizziamo nella variabile rimossa usando Underscore è uguale()
metodo.
Se la è uguale()
il metodo restituisce true, quindi chiamiamo il codice JavaScript nativo splice ()
metodo sul contatti
array, passando l'indice dell'elemento da rimuovere e il numero di elementi da rimuovere. L'indice è ottenuto usando Underscore indice di()
metodo che abbiamo usato in precedenza.
Ora, quando si fa clic su un pulsante di eliminazione, la vista, il modello e i dati originali verranno cancellati dall'esistenza. Possiamo anche filtrare la vista, quindi tornare alla visualizzazione di tutti i contatti e il contatto rimosso non verrà ancora visualizzato.
Quindi, abbiamo appena scaricato il Agg.contatto
forma sulla pagina non ci siamo? Per chiudere questa parte del tutorial, possiamo fare qualcosa per tenerlo nascosto fino a quando non viene cliccato un link. Possiamo aggiungere il seguente link al elemento:
Aggiungi nuovo contatto
Per fare in modo che il link mostri il modulo, prima dobbiamo nasconderlo e poi usare un gestore di eventi dell'interfaccia utente per mostrarlo. La rilegatura può essere aggiunta al eventi
oggetto nel DirectoryView
classe:
"fai clic su #showForm": "showForm"
Nostro ShowForm ()
il metodo può essere semplice come segue (anche se probabilmente vorrai fare un po 'più di quello che facciamo qui!):
showForm: function () this. $ el.find ("# addContact"). slideToggle ();
In questo tutorial, abbiamo esaminato esclusivamente come i nuovi modelli possono essere aggiunti a una collezione e come i modelli possono essere rimossi da una collezione. Abbiamo visto che i metodi Backbone usati per aggiungere e rimuovere i modelli sono, ovviamente, i Inserisci()
e rimuovere()
metodi.
Abbiamo anche visto come possiamo associare i gestori agli eventi che vengono generati automaticamente quando questi metodi vengono utilizzati per aggiornare l'interfaccia utente e la raccolta come necessario.
Abbiamo anche esaminato alcune funzioni utili dell'utilità Underscore che possiamo usare per lavorare con i nostri dati, incluso _indice di()
che restituisce quell'indice di un elemento in un array, e è uguale()
che può essere usato per confrontare a fondo due oggetti per vedere se sono identici.
Come nell'ultima parte di questo tutorial, abbiamo anche visto come è possibile scrivere le nostre classi in modo tale che le loro funzionalità possano essere condivise e riutilizzate quando possibile. Ad esempio, quando abbiamo aggiunto un nuovo modello, abbiamo utilizzato l'esistente renderContact ()
metodo definito nel nostro DirectoryView
classe per gestire il rendering dell'HTML per il nuovo contatto.
Quindi abbiamo visto come aggiungere modelli e rimuoverli, unitevi a me nella prossima parte di questa serie in cui vedremo come modificare i dati del modello esistente.