Diversi posti nella mia applicazione Backbone Mi piacerebbe avere una ricerca istantanea su una raccolta, ma sto avendo difficoltà a trovare il modo migliore per implementare esso.Backbone.js - Best practice per l'implementazione della ricerca "istantanea"
Ecco una rapida implementazione. http://jsfiddle.net/7YgeE/ Ricorda che la mia collezione potrebbe contenere fino a 200 modelli.
var CollectionView = Backbone.View.extend({
template: $('#template').html(),
initialize: function() {
this.collection = new Backbone.Collection([
{ first: 'John', last: 'Doe' },
{ first: 'Mary', last: 'Jane' },
{ first: 'Billy', last: 'Bob' },
{ first: 'Dexter', last: 'Morgan' },
{ first: 'Walter', last: 'White' },
{ first: 'Billy', last: 'Bobby' }
]);
this.collection.on('add', this.addOne, this);
this.render();
},
events: {
'keyup .search': 'search',
},
// Returns array subset of models that match search.
search: function(e) {
var search = this.$('.search').val().toLowerCase();
this.$('tbody').empty(); // is this creating ghost views?
_.each(this.collection.filter(function(model) {
return _.some(
model.values(),
function(value) {
return ~value.toLowerCase().indexOf(search);
});
}), $.proxy(this.addOne, this));
},
addOne: function(model) {
var view = new RowView({ model: model });
this.$('tbody').append(view.render().el);
},
render: function() {
$('#insert').replaceWith(this.$el.html(this.template));
this.collection.each(this.addOne, this);
}
});
E una piccola vista per ogni modello ...
var RowView = Backbone.View.extend({
tagName: 'tr',
events: {
'click': 'click'
},
click: function() {
// Set element to active
this.$el.addClass('selected').siblings().removeClass('selected');
// Some detail view will listen for this.
App.trigger('model:view', this.model);
},
render: function() {
this.$el.html('<td>' + this.model.get('first') + '</td><td>' + this.model.get('last') + '</td>');
return this;
}
});
new CollectionView;
Domanda 1
Su ogni keydown, a filtrare la collezione, vuoto il tbody
, e rendere il risultati, creando così una nuova vista per ogni modello. Ho appena creato una vista fantasma, sì? Sarebbe meglio distruggere adeguatamente ogni vista? O dovrei tentare di gestire il mio RowView
s ... creando ognuno una sola volta e scorrendo attraverso di essi per rendere solo i risultati? Un array nel mio CollectionView
forse? Dopo aver svuotato il tbody
, il dovrebbe ancora avere il valore el
oppure ora è nullo e deve essere nuovamente sottoposto a rendering?
Domanda 2, Selezione del modello
Noterete sto innescando un evento personalizzato nel mio RowView
. Mi piacerebbe avere una vista dettagliata da qualche parte per gestire quell'evento e visualizzare l'interezza del mio modello. Quando cerco la mia lista, se il mio modello selezionato rimane nei risultati di ricerca, voglio mantenere quello stato e lasciarlo nella mia vista di dettaglio. Una volta che non è più nei miei risultati, svuoterò la vista di dettaglio. Quindi dovrò sicuramente gestire una serie di viste, giusto? Ho considerato una struttura doppiamente collegata in cui ogni vista indica il suo modello e ogni modello per la sua vista ... ma se devo implementare una fabbrica singleton sui miei modelli in futuro, non posso imporlo sul modello. :/
Quindi qual è il modo migliore per gestire queste visualizzazioni?
Grazie, questo è estremamente utile. Mi piace molto quello che hai fatto con il filtro. Nei miei primi tentativi avevo anche lo scope, ma era difficile da codificare e in qualche modo mi mancava la funzione 'pick' nei documenti. Inoltre, non ho mai saputo della funzione 'throttle', anche molto utile. –
Sto ancora spostando la testa nel modo in cui hai reso le cose, e non sono abbastanza venduto sull'uso di 'setElement'. Mi sembra inelegante essere ri-legare gli eventi ad ogni rendering. Non ho mai visto questa tecnica di innesto, dove si rendono gli elementi della lista in CollectionView e si innestano sulle ItemViews ... Non sono abituato a ItemView che non è responsabile del rendering stesso, e da un lato sembra una separazione di preoccupazioni che non dovrebbero verificarsi, ma d'altra parte è sorprendentemente semplice in quanto è sempre più facile avere il modello iterato sulle nostre collezioni. –
@savinger 'setElement' è per lo più per ragioni estetiche e per" autosufficienza "dei modelli, questa tecnica sarebbe più utile se fosse necessario rieseguire il rerender delle righe, ad esempio. Questa risposta può aiutarti a capire il mio punto di vista http://stackoverflow.com/questions/12004534/backbonejs-rendering-problems/12006179#12006179 – nikoshr