2012-07-19 4 views
0

Bit d'un intrus ...Backbone.js pas Itère collection

J'ai la collection:

class Store.Collections.Product extends Backbone.Collection 

    url: '/api/products' 

    model: Store.Models.Product 

Avec la vue:

class Store.Views.Origin extends Backbone.View 

    initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.fetch() 
    @model.bind('change:formatted', @render, this); 
    @render() 

    events: 
    'change [name=origin]': 'setOrigin' 

    el: => 
    @options.parent.$('.origin-input')[0] 

    template: JST["backbone/templates/shapes/product"] 

    render: -> 
    $this = $(this.el) 
    $this.html(@template(model: @model.toJSON(), errors: @model.errors)) 
    console.log(@collection) 
    @collection.each(@appdenDropdown) 
    @delegateEvents() 
    this 

    appdenDropdown: (product) -> 
    console.log("append trigger") 
    #view = new Store.Views.Products(model: product) 
    #$('#history').append(view.render().el) 

avec le modèle:

<div id="history"></div> 

La collection fonctionne ... le

console.log(@collection) 

affiche les données! cependant

@collection.each(@appdenDropdown) 

Ne fait rien, ne fait pas d'erreur, ou par quoi que ce soit. Ça ne fait rien. J'essaie d'extraire les données de la collection! Mais il ne sera pas ...

+0

Vérifier http://stackoverflow.com/questions/8413500/backbone-js-populating-a-collection/ 8415515 # 8415515 ou http://stackoverflow.com/questions/11459244/backbone-js-empty-array-attribute/11463190#11463190 – nikoshr

+2

btw: pourquoi faire '$ this = ... 'quand VOUS AVEZ' this. $ El '. Je suggère de lire la documentation de backbone.js. – jakee

+0

et effacez la réponse de nikoshr: collection.fetch est 'asynchrone' et vous affichez votre vue dans la méthode initialize probablement avant le retour de fetch, donc la collection est vide. Le fichier console.log est 'wtfsynchronous', donc il enregistre la collection comme étant remplie. Ce que vous avez à faire est de lier la méthode de rendu à l'événement reset de la collection pour vous assurer que la vue est restituée après que la collection soit remplie – jakee

Répondre

3

C'est parce qu'il n'y a rien encore dans la collection.

@collection.fetch() dans l'initialiseur est une méthode asynchrone. Vous devez attendre que l'extraction soit terminée avant de parcourir les éléments de la collection.

La fonction fetch() prend en compte un rappel de succès facultatif déclenché à la fin de l'extraction.

Vous pouvez donc mettre à jour votre code d'initialisation pour attendre que la collection soit récupérée avant d'appeler render. Voici le code.

initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.fetch 
    success: => 
     @render() 
+0

pouvez-vous tout arrêter jusqu'à ce que la collection soit remplie? –

+0

@CharlieDavies J'ai mis à jour ma réponse pour refléter votre question – Paul

+1

@CharlieDavies Ce genre de défaites le MVC d'attendre comme ça. Une autre façon de l'aborder est de faire en sorte que la vue écoute la collection à réinitialiser pour exécuter votre rendu. this.collection.on ('reset', this.render, this); Donc, quand vous faites votre fetch (qui déclenche un événement 'reset'), le rendu sera automatiquement appelé. –

0

Le problème que d'autres ont mentionné que fetch est asynchrone, mais la solution est simple: objet jQuery deferred:

initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.deferred = @collection.fetch() 

    @model.bind('change:formatted', @render, this); 
    @collection.deferred.done -> 
    @render() 

Ce qui se passe ici est que lorsque vous appelez @collection.deferred.done, vous indiquez jQuery attend jusqu'à ce que la collection soit chargée avant d'exécuter render dessus, ce que vous voulez. Je pense que cela devrait fonctionner.

Quelques bonnes références sur deferred:

+0

Correction: Je pense que la réponse de @ Paul en utilisant le rappel 'de succès 'fait la même chose. –

+0

Merci pour votre aide, cela me semble beaucoup plus logique maintenant! Vraiment apprécié! –

Questions connexes