2013-07-03 20 views
11

Ich habe eine App im Backbone, die Daten von einem Server abrufen. Diese Daten sind Hotels und foreach Hotel habe ich mehr Räume. Ich habe Hotel in ein Json aufgeteilt und Zimmer in einem anderen json wie folgt aus:Backbone verschachtelte Sammlung

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" 
    } 
] 

Ich nehme möchte jedes Hotel und verbinden sich mit seinen Zimmern (externer Schlüssel in rooms.jsonhotel_id) und drucken Sie die Kombination der Räume aus: foreach Ebene kombinieren verschiedene Räume.

Ein Zimmer von Ebene 1, ein Raum der Ebene 2 und einem Raum von Level 3.

Maximal Level 3, aber ich kann nur eine Ebene oder nur zwei Pegel aufweist. Wenn ich 3-Ebene habe ich möchte nicht Kombination von Level 1 und Level 2 ohne Stufe 3.

So etwas wie dieses

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" 

den Konstruktor dieses Ich denke Zimmer ist in renderRooms in meine App einfügen.

Das ist meine App:

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") 
}); 

Wie kann ich diesen Raum Kombination erstellen und drucken?
Gibt es einen guten Weg oder gibt es etwas Besseres?

+0

Ich habe Ihre Fragen im Anschluss an diese Frage in Bezug auf und es scheint, wie Sie habe mehrere Probleme, die Sie versuchen zu erarbeiten. Was Sie wirklich brauchen, ist die kartesische Funktion, die @Bergi in dieser Frage http://stackoverflow.com/questions/17417589/recursive-function-jquery-with-backbone vorgeschlagen hat. Ich würde diesen Weg fortsetzen. –

+0

Ich habe bereits versucht, aber scheint, dass das nicht funktioniert, Array der ersten groupBy ist leer Ich weiß nicht, warum .. @moderndegree –

+0

Ich legte ein Update auf @ Bergis Antwort auf diese Frage (http://StackOverflow.com/) Fragen/17417589/rekursive-Funktion-jquery-mit-Backbone). In der Zwischenzeit können Sie ein funktionierendes Beispiel hier sehen: http://plnkr.co/edit/NHE9V5?p=preview. –

Antwort

20

Hier ist, wie Sie die Kollektionen strukturieren:

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 
}); 

Dann können Sie etwas tun:

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

Hallo Ich weiß, das ist eine alte Antwort, aber sollten keine Räume zu 'this.attributes' hinzugefügt werden, nicht nur' this', da du 'model.get ('rooms') nicht tun kannst.' – Quince

+1

Dies ist da 'rooms' ist eine Collection und muss direkt adressiert werden, anstatt über 'get()' oder 'set()'. Wenn Sie beispielsweise 'set ('rooms', [])' aufrufen würden, wäre die Sammlung nicht mehr synchron. Ich nehme an, du könntest es überarbeiten, um 'change: rooms' anzuhören und es so zu handhaben, aber es schien einfach eine Menge Arbeit zu sein. –

+0

Wenn 'rooms' eine Sammlung innerhalb Ihres Modellattribut-Hashes ist, können Sie' get ('rooms'). Reset ([]) 'verwenden, um eine nicht synchrone Sammlung zu vermeiden und es auch nicht zu hören. –

Verwandte Themen