2013-07-03 22 views
11

Mam aplikację w szkielecie, która pobiera dane z serwera. Te dane są hotele i hotel foreach Mam więcej pokoi. Mam podzielone hotelu w json i pomieszczeń wewnątrz innego json tak:Kolekcja zagnieżdżona szkieletowa

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

chcę wziąć każdy hotel i połączyć z jego pokoi (klucz zewnętrzny do rooms.jsonhotel_id) i wydrukuj kombinację pokoi: poziom foreach łączy różne pokoje.

jeden pokój z poziomu 1, jeden pokój poziomu 2 i jedno pomieszczenie poziomu 3.

maksymalny poziom wynosi 3, ale można mieć tylko jeden poziom, czy tylko dwa poziomy. Jeśli mam 3 Poziom Nie chcę kombinacji poziom 1 i 2 bez poziomie 3.

coś takiego

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" 

konstruktora tego pokoju moim zdaniem jest wstawić do renderRooms w mojej aplikacji.

To moja aplikacja:

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

Jak mogę tworzyć to połączenie salonu i wydrukować go?
Czy jest dobry sposób, czy jest coś lepszego?

+0

śledzę Twoje inne pytania dotyczące tej kwestii i wydaje się, jak ty Mam kilka problemów, które próbujesz wypracować. To, czego naprawdę potrzebujesz, to funkcja kartezjańska, którą @Bergi zasugerował w tym pytaniu: http://stackoverflow.com/questions/17417589/recursive-function-jquery-with-backbone. Kontynuowałbym tę ścieżkę. –

+0

Próbowałem już, ale wydaje się, że to nie działa, tablica pierwszej grupy jest pusta Nie wiem dlaczego ... @moderndegree –

+0

Złożyłem aktualizację odpowiedzi @ Bergi na to pytanie (http://stackoverflow.com/ pytania/17417589/recursive-function-jquery-with-backbone). W międzyczasie możesz zobaczyć działający przykład: http://plnkr.co/edit/NHE9V5?p=preview. –

Odpowiedz

20

Oto w jaki sposób można uporządkować te Kolekcje:

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

Następnie można zrobić coś takiego:

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

Witam Wiem, że jest to stara odpowiedź, ale nie należy dodawać pokoi do 'this.attributes' nie tylko' this', ponieważ nie można tego zrobić 'model.get ('rooms')' – Quince

+1

Dzieje się tak, ponieważ 'rooms' jest zbiorem i należy się nim zająć bezpośrednio, a nie poprzez 'get()' lub 'set()'. Na przykład, jeśli miałbyś wywołać 'set ('rooms', [])', kolekcja byłaby niezsynchronizowana. Sądziłem, że możesz przerobić to, żeby posłuchać 'change: rooms' i poradzić sobie z tym w ten sposób, ale to po prostu wydawało się dużo pracy. –

+0

Jeśli 'rooms' jest zbiorem wewnątrz twojego atrybutu atrybutów modelu, możesz po prostu użyć' get ('rooms'). Reset ([]) ', aby uniknąć zbędnej synchronizacji, a także unikaj jej słuchania. –