7

Tengo un enrutador accediendo a su colección. My for loop no estaba iterando a través de los modelos, así que intenté iniciar sesión en la colección para ver qué devolvía. Resulta que cuando registro la colección directamente veo todos los modelos como se esperaba. ¡Pero si trato de registrar el atributo de modelos de la colección, obtengo una matriz vacía! No tiene sentido. Estas líneas se siguen directamente entre sí. Intenté cambiar el orden y obtuve el mismo resultado.¿Por qué backbone.js devuelve una matriz vacía al acceder a los modelos?

console.log(this.collection); 
=> Shots 
    _byCid: Object 
    _byId:  Object 
    length: 15 
    models: Array[15] 
    __proto__: Shots 
    ... 

console.log(this.collection.models); 
=> [] 

console.log(this.collection.length); 
=> 0 

¿Por qué sucedería esto?

Este es el código como lo es en el router para dar un mejor contexto de donde está disparando este código:

# Routers 
class Draft.Routers.Shots extends Backbone.Router 
    routes: 
    ''   : 'index' 
    'shots/:id' : 'show' 

    initialize: -> 
    @collection = new Draft.Collections.Shots() 
    @collection.fetch() 

    index: -> 
    console.log @collection 
    console.log @collection.models 
+1

¿Terminó la búsqueda y se restableció con éxito o agregó modelos a la colección en el momento de la sesión? – user500198

+0

solo puedo suponer que sí, los 2 registros están uno detrás del otro, sería una cuestión de nanosegundos entre esas dos llamadas. aún es posible, pero al menos debería ser un resultado inestable si lo prueba varias veces ... no siempre se puede terminar de cargar justo entre esas dos llamadas de registro. – Sander

+1

No entiendo por qué estaba registrando pero descubrí que necesito agregar un detector de eventos en la colección dentro de la vista para asegurarme de que se haya cargado. –

Respuesta

2

encontré que necesitaba escuchar para la recogida restablecer. Entonces, en lugar de pasar el modelo a la vista, creé otra vista esperando la colección y escuché el evento 'reiniciar' para disparar 'renderizar' para la vista.

# Routers 
class Draft.Routers.Shots extends Backbone.Router 
    routes: 
    ''   : 'index' 
    'shots/:id' : 'show' 

    initialize: -> 
    @collection = new Draft.Collections.Shots() 
    @collection.fetch() 

    index: -> 
    view = new Draft.Views.Desktop(collection: @collection) 

# Views 
class Draft.Views.Desktop extends Backbone.View 
    el: $("body") 

    initialize: -> 
    @collection.on("reset",@render,this) 

    render: -> 
    console.log @collection 
    console.log @collection.length 
5

Jim,

esto no soluciona el problema - que ha trabajado de eso. Pero explica por qué está viendo la salida de la consola que ve.

Cuando ejecuta console.log (esto), saca el objeto en sí y la consola vincula referencias (punteros si lo desea) a las variables internas.

Cuando estás mirando en la consola, en el momento de la console.log (este) carreras del área de los modelos está vacía, pero en el momento de mirar en los registros, la colección ha terminado cargando los modelos y la variable de matriz interna se actualiza, Y la referencia a esa variable en el registro de objeto muestra el contenido actual.

Básicamente en console.log (esto), la variable de modelos internos continúa su vida normal y la consola muestra el estado actual en el momento en que lo está mirando, no en el momento en que lo llamó. Con console.log (this.models), la matriz se vacía como está, no se guarda ninguna referencia y todos los valores internos se vuelcan uno por uno ..

Ese comportamiento es bastante simple de reproducir con un tiempo de espera corto, mira este violín ... http://jsfiddle.net/bendog/XVkHW/

+0

¡Gracias! Eso es realmente interesante y bueno saberlo en el futuro. Estaba realmente confundido allí. –

+0

@JimJeffers. Sin preocupaciones, me alegro de traer algo de luz, pasé por la misma confusión antes ... :) – Ben

0

Puedes hacer una promesa. (.done va a funcionar bien)

@collection.fetch().done => 
    for model in @collection.models 
    console.log model 

esto le dará los modelos de @ collection recogidos y listos para funcionar.

o si no es necesario forzar la aplicación que esperar,

@collection.on 'sync', => 
    for model in @collection.models 
    console.log model 

Ambos le permitirá hacer lo que quiere.

Cuestiones relacionadas