2013-07-03 4 views
11

J'ai une application dans le backbone qui récupère des données d'un serveur. Ces données sont des hôtels et chaque hôtel j'ai plus de chambres. J'ai divisé en un hôtel JSON et des chambres dans un autre JSON comme ceci:Collection imbriquée backbone

hotel.json

[ 
    { 
    "id": "1", 
    "name": "Hotel1" 
    }, 
    { 
    "id": "2", 
    "name": "Hotel2" 
    }, 
    { 
    "id": "3", 
    "name": "Hotel3" 
    } 
] 

rooms.json

[ 
    { 
    "id" : "r1", 
    "hotel_id" : "1", 
    "name" : "Singola", 
    "level" : "1" 
    }, 
    { 
    "id" : "r1_1", 
    "hotel_id" : "1", 
    "name" : "Doppia", 
    "level" : "2" 
    }, 
    { 
    "id" : "r1_3", 
    "hotel_id" : "1", 
    "name" : "Doppia Uso singol", 
    "level" : "1" 
    }, 
    { 
    "id" : "r2", 
    "hotel_id" : "2", 
    "name" : "Singola", 
    "level" : "1" 
    }, 
    { 
    "id" : "r2_1", 
    "hotel_id" : "2", 
    "name" : "Tripla", 
    "level" : "1" 
    } 
] 

Je veux prendre chaque hôtel et ses chambres avec combinerai (touche externe dans rooms.jsonhotel_id) et imprimez la combinaison des pièces: pour chaque niveau, combinez différentes pièces.

Une chambre de niveau 1, une chambre de niveau 2 et une chambre de niveau 3.

maximum de niveau est 3 mais je ne peux avoir qu'un seul niveau ou seulement deux niveaux. Si j'ai 3 niveau que je ne veux pas combinaison de niveau 1 et niveau 2 sans niveau 3.

Quelque chose comme ça

Room "Single", "level" : "1" , "hotel_id" : "1" 
Room "Double", "level" : "2" , , "hotel_id" : "1" 
Room "Triple", "level" : "3" , , "hotel_id" : "1" 

Room "Double for single", "level" : "1" , "hotel_id" : "1" 
Room "Double", "level" : "2" , , "hotel_id" : "1" 
Room "Triple", "level" : "3" , , "hotel_id" : "1" 

Le constructeur de cette chambre, je pense est mettre en renderRooms dans mon application.

Ceci est mon application:

var Room = Backbone.Model.extend(); 
var Rooms = Backbone.Collection.extend({ 
    model: Room, 
    url: "includes/rooms.json" 
}); 
var Hotel = Backbone.Model.extend({ 
    defaults: function() { 
     return { 
      "id": "1", 
      "name": "Hotel1", 
      "rooms": [] 
     } 
    } 
}); 
var HotelCollection = Backbone.Collection.extend({ 
    model: Hotel, 
    url: "includes/test-data.json", 
    initialize: function() { 
     console.log("Collection Hotel initialize"); 
    } 
}); 
var HotelView = Backbone.View.extend({ 
    template: _.template($("#hotel-list-template").html()), 
    initialize: function() { 
     this.collection = new HotelCollection(); 
     this.collection.bind('sync', this.render, this); 
     this.collection.fetch(); 
    }, 
    render: function() { 
     console.log('Data hotel is fetched'); 
     this.bindRoomToHotel(); 
     var element = this.$el; 
     element.html(''); 
    }, 
    bindRoomToHotel: function() { 
     allRooms = new Rooms(); 
     allRooms.on("sync", this.renderRooms, this) 
     allRooms.fetch(); 
    }, 
    renderRooms: function() { 


     $(this.el).html(this.template({ hotels: this.collection.models })); 
    } 
}); 

var hotelView = new HotelView({ 
    el: $("#hotel") 
}); 

Comment puis-je créer cette combinaison de chambre et l'imprimer?
Y at-il un bon moyen ou il y a quelque chose de mieux?

+0

J'ai suivi vos autres questions à ce sujet et il semble que vous Vous avez plusieurs problèmes que vous essayez de résoudre. Ce dont vous avez vraiment besoin, c'est la fonction cartésienne que @Bergi a suggérée dans cette question http://stackoverflow.com/questions/17417589/recursive-function-jquery-with-backbone. Je continuerais dans cette voie. –

+0

J'ai déjà essayé mais semble que cela ne fonctionne pas, tableau de premier groupeBy est vide, je ne sais pas pourquoi .. @moderndegree –

+0

J'ai soumis une mise à jour à la réponse @ Bergi à cette question (http://stackoverflow.com/ questions/17417589/recursive-function-jquery-with-backbone). En attendant, vous pouvez voir un exemple de travail ici: http://plnkr.co/edit/NHE9V5?p=preview. –

Répondre

20

Voici comment vous pouvez structurer les collections:

HotelModel = Backbone.Model.extend({ 
    initialize: function() { 
     // because initialize is called after parse 
     _.defaults(this, { 
      rooms: new RoomCollection 
     }); 
    }, 
    parse: function(response) { 
     if (_.has(response, "rooms")) { 
      this.rooms = new RoomCollection(response.rooms, { 
       parse: true 
      }); 
      delete response.rooms; 
     } 
     return response; 
    }, 
    toJSON: function() { 
     var json = _.clone(this.attributes); 
     json.rooms = this.rooms.toJSON(); 
     return json; 
    } 
}); 

RoomModel = Backbone.Model.extend({ 
}); 

HotelCollection = Backbone.Collection.extend({ 
    model: HotelModel 
}); 

RoomCollection = Backbone.Collection.extend({ 
    model: RoomModel 
}); 

Ensuite, vous pouvez faire quelque chose comme ceci:

var hotels = new HotelCollection(); 
hotels.reset([{ 
    id: 1, 
    name: 'Hotel California', 
    rooms: [{ 
     id: 1, 
     name: 'Super Deluxe' 
    }] 
}], { 
    parse: true // tell the collection to parse the data 
}); 

// retrieve a room from a hotel 
hotels.get(1).rooms.get(1); 

// add a room to the hotel 
hotels.get(1).rooms.add({id:2, name:'Another Room'}); 
+0

Salut, je sais que c'est une vieille réponse, mais les chambres ne devraient pas être ajoutées à 'this.attributes', pas seulement' this', car vous ne pouvez pas faire 'model.get ('rooms')' – Quince

+1

Ceci est dû au fait que 'rooms' est une collection et doit être adressée directement, plutôt que via 'get()' ou 'set()'. Par exemple, si vous deviez appeler 'set ('rooms', [])', la collection serait désynchronisée. Je supposais que vous pouviez le retravailler pour écouter 'changer: les pièces 'et le gérer de cette façon, mais cela semblait être beaucoup de travail. –

+0

Si 'rooms' est une collection dans le hachage des attributs de votre modèle, vous pouvez juste utiliser' get ('rooms'). Reset ([]) 'pour éviter la désynchronisation et éviter de l'écouter. –

Questions connexes