modelli Disappearing in collezione Backbone
-
22-10-2019 - |
Domanda
Ho un modello di Backbone line
che contiene una raccolta di modello Stop
.
Ad un certo punto, voglio per scorrere le tappe in linea e ottenere il tempo totale di viaggio lungo la linea, utilizzando la funzione di reduce
Underscore.
Questo non funziona, però. Sembra che succede qualcosa con la raccolta ad un certo punto. Sembra di contenere un solo oggetto senza attributi significativi, anche se so per certo che è stato popolato con quattro sportelli modelli con attributi validi.
Il modello:
App.models.Line = Backbone.Model.extend({
initialize: function() {
var stops = new App.models.Stops({
model: App.models.Stop,
id: this.get("id")
});
stops.fetch();
this.set({
stops: stops
});
this.set({unique: true});
this.calculateTotalTime();
},
calculateTotalTime: function() {
this.get("stops").each(function(num) {
console.log("Model!");
});
console.log("Unique: ", this.get("unique"));
}
});
Console stampa è:
Model!
Unique: true
Non ci dovrebbero essere quattro "Modello!", Dal momento che il numero di modelli è di quattro.
La cosa più strana è che tutto funziona bene nella console:
window.line.get("stops").each(function(num) {
console.log("Model!");
});
Model!
Model!
Model!
Model!
Il JS è stato compilato con Sprockets:
//= require ./init
//= require ./lib/jquery
//= require ./lib/underscore
//= require ./lib/backbone
//= require ./lib/raphael
//= require_tree ./controllers
//= require_tree ./models
//= require_tree ./views
//= require ./main
Init.js:
window.App = {};
App.views = [];
App.models = [];
main.js:
$(function() {
window.line = new App.models.Line({name: "4", id: 4});
window.lineView = new App.views.Line({model: line});
$("#outer").append(lineView.render().el);
});
Alcuni altri comportamenti strani:
console.log(this.get("stops"))
nel modello produce questo oggetto abbastanza normale:
child
_byCid: Object
_byId: Object
_onModelEvent: function () { [native code] }
_removeReference: function () { [native code] }
id: 4
length: 4
models: Array[4]
0: Backbone.Model
1: Backbone.Model
2: Backbone.Model
3: Backbone.Model
length: 4
__proto__: Array[0]
__proto__: ctor
Ma chiamando console.log(this.get("stops").models)
, che dovrebbe produrre la matrice, solo che questa ritorni, una matrice di un singolo oggetto senza attributi utili:
[
Backbone.Model
_callbacks: Object
_changed: false
_changing: false
_escapedAttributes: Object
_previousAttributes: Object
attributes: Object
id: 4
model: function (){ return parent.apply(this, arguments); }
__proto__: Object
cid: "c1"
id: 4
__proto__: Object
]
ho il sospetto questo è tutta una questione di qualche malinteso sulla natura del this
. Sono contento per tutto l'aiuto fornito.
Soluzione
stops.fetch()
è un processo asincrono, in modo che il codice che avete scritto subito dopo sarà probabilmente il fuoco prima che i risultati del recupero sono tornati dal server.
è necessario modificare il codice per eseguire tutto dopo l'operazione di recupero torna. il modo più semplice per farlo è con l'evento reset
dalla raccolta stops
:
App.models.Line = Backbone.Model.extend({
initialize: function() {
var stops = new App.models.Stops({
model: App.models.Stop,
id: this.get("id")
});
// store the stops, and then bind to the event
this.set({stops: stops});
stops.bind("reset", this.stopsLoaded, this);
stops.fetch();
},
stopsLoaded: function(){
// get the stops, now that the collection has been populated
var stops = this.get("stops");
this.set({unique: true});
this.calculateTotalTime();
},
calculateTotalTime: function() {
this.get("stops").each(function(num) {
console.log("Model!");
});
console.log("Unique: ", this.get("unique"));
}
});
il motivo per cui funziona nella vostra console è perché per il momento si digita il codice per valutare fermate del modello, la chiamata fetch
è già tornato e popolato la collezione.
speranza che aiuta ??p>