2012-01-16 3 views
3

Solution dans mon itinérairepeuplant collection imbriquée avec JSON imbriqué

 
Myapp.Routes = Backbone.Router.extend({ 
    init: function(){ 
     user = new User(); 
     user.fetch({user, 
        success: function(response){ 
          user.classlist = new classes(response.attributes.classes); 
      }); 

    } 

}); 

J'ai un tableau de JSON sérialisé être renvoyé de mon serveur, et je suis en train de mettre les objets imbriqués dans mes collections imbriquées. Cette réponse, je pensais allait m'y amener, mais il me manque quelque chose. How to build a Collection/Model from nested JSON with Backbone.js

JSON que je suis en train de remplir mon modèle imbriqué avec est

 
{first_name: "Pete",age: 27, classes: [{class_name: "math", class_code: 42},{class_name: "french", class_code: 18}]} 

Je crée mon modèle utilisateur

 
MyApp.Models.Users = = Backbone.Model.extend({ 

    initialize: function(){ 
     this.classlist = new MyApp.Collections.ClassList(); 

     this.classlist.parent = this; 

    } 

}); 

J'avais essayé de suivre l'exemple de l'autre page, et utiliser

 
     this.classlist = new MyApp.Collections.ClassList(this.get('classes')); 

     this.classlist.parent = this; 

mais this.get('classes') retu rns indéfini.

J'ai également essayé d'obtenir le tableau de classes à travers this.attributes.classes, mais c'est aussi indéfini.

------------ mise à jour pour inclure la réinitialisation -------------------- La fonction où j'initialise le L'utilisateur et les classes se trouvent dans les routes utilisateur et sont appelés ré-initialiser. J'utilise cette fonction pour récupérer l'utilisateur et ses classes et stocker l'objet.

 
re_initialize: function(id){ 
      user = new MyApp.Models.User(); 
      MyApp.editingClasses.url = 'classes/'+id; 
      MyApp.editingClasses.fetch({ 
         success: function(response){ 
         MyApp.editingClasses.parse(response); 
         } 
      }); 

     new MyApp.Views.ClassesInput(); 
    }, 

Comme vous pouvez le voir, j'appelle la parse explicitement dans la fonction de la réussite, mais il est de ne pas ajouter les classes à la collection.

Je ne peux pas inclure la 'collection' car pour une raison quelconque je ne peux pas y accéder dans le backbone. le modèle de l'utilisateur, après avoir été renvoyé à backbone comprend le tableau de classes, que j'essaie de mettre dans la collection ClassList.

L'objet de modèle utilisateur copié à partir du terminal javascript ressemble à ceci.

 
attributes: Object 
created_at: "2012-01-05T16:05:19Z" 
id: 63 
classes: Array[3] 
    0: Object 
    created_at: "2012-01-18T20:53:34Z" 
    id: 295 
    teacher_id: 63 
    class_code: 42 
    updated_at: "2012-01-18T20:53:34Z" 
    class_name: math 
    __proto__: Object 
    1: Object 
    2: Object 
    length: 3 
    __proto__: Array[0] 
+0

peut vous envoyer plusieurs codes? la collection par exemple? – trouble

+0

@trouble, j'ai mis à jour la question pour inclure ma fonction 're-initailize' et l'objet comme backbone le voit, bien que comme je le mentionne plus haut, je ne peux pas accéder aux classes par 'user.attributes.classes' – pedalpete

Répondre

9

Vous pouvez utiliser la fonction parse pour prétraiter la réponse du serveur:

MyApp.Models.Users = Backbone.Model.extend({ 
    parse: function(response) { 
    var classesJSON = response.classes; 
    var classesCollection = MyApp.Collections.ClassList(classesJSON); 
    response.classes = classesCollection; 
    return response; 
    } 
}); 

var user = new MyApp.Models.Users(); 
user.fetch(); 

// You should now be able to get the classlist with: 
user.get('classes'); 

Cela dit, l'approche proposée dans l'autre question devrait également fonctionner. Il se peut que lorsque votre fonction initialize est appelée, le modèle n'a pas encore été rempli avec les données?

Par exemple, si vous faites:

var user = new MyApp.Models.Users(); 

Il n'aura pas d'attributs encore pour donner à la collection de liste des élèves. Cela pourrait-il être votre problème?

+0

pas de chance, j'obtiens le modèle utilisateur par 'fetch()', mais bien sûr, comme vous l'avez dit, il n'a aucun attribut quand j'initialise, avant d'exécuter fetch, qui est je devine pourquoi je ne vois pas le résultat. Y a-t-il un moyen de créer le modèle et d'aller chercher en même temps? – pedalpete

+0

vous pouvez utiliser la méthode 'parse' de la première partie de ma réponse. – satchmorun

+0

Malheureusement, la méthode 'parse' ne fonctionne pas non plus. Ai-je besoin de l'appeler explicitement? – pedalpete

4

OK!vous pouvez peut-être chercher les classes de cette façon:

Modèle:

window.person = Backbone.Model.extend({ 
defaults: { } 
}); 

Collection:

window.ClassesCollection = Backbone.Collection.extend({ 
model: person, 
url: "http://your/url/data.json", 
parse: function(response){ 
    return response.classes; 
} 
}); 

Router:

window.AppRouter = Backbone.Router.extend({ 
routes: { 
    "" : "init" 
}, 

init: function(){  
    this.classesColl = new ClassesCollection(); 
    this.classesColl.fetch(); 
    this.classesView = new ClassesView({collection: this.classesColl});  
} 
}); 

Vue: (pour le rendu toutes les classes)

window.ClassesView = Backbone.View.extend({ 
    el: $('...'), 
    template: _.template($("...").html()), 

    initialize: function() { 
    this.collection.bind("reset", this.render, this); 
    }, 
    render: function(collection) { 

    _.each(collection.models, function(obj){ 
     ... 
     //obj.get('class_name') or obj.get('class_code') 
     ... 
    }, this); 
     ... 
    return this; 
    } 
}); 
+0

Fermer, mais pas tout à fait (même si je vais vous donner la victoire de toute façon pour votre dur effort, et merci, comme vous me menez à la réponse.) Le problème avec cette solution (d'après ce que je vois) est que vous suggérez que je fasse un deuxième «fetch» ​​pour les classes, et ce n'est pas correct J'ai commenté la solution ci-dessus, car c'était beaucoup plus proche de ce que j'ai fini avec. – pedalpete