Recursive function jquery with backbone

后端 未结 2 1065
逝去的感伤
逝去的感伤 2021-01-26 13:40

I have an app in backbone where I want to find inside a Json some records and print out.

my JSON is like this:

[
  {
    \"id\" : \"r1\",
    \"hotel_id\         


        
相关标签:
2条回答
  • 2021-01-26 14:04

    Based on @Bergi's answer, I came up with this. It should solve your problem.

    Here is a demo: http://plnkr.co/edit/NHE9V5?p=preview

    Updated I have modified some things to accomodate your separate JSON files.

    Cartesian Product Helper (http://en.wikipedia.org/wiki/Cartesian_product)

    function cartesian(arg) {
      arg = arg || [];
      var r = [],
            max = arg.length - 1;
    
        function helper(arr, i) {
            for (var j = 0, l = arg[i].length; j < l; j++) {
                var a = arr.slice(0); // clone arr
                a.push(arg[i][j]);
                if (i == max) {
                    r.push(a);
                } else helper(a, i + 1);
            }
        }
      if(arg.length > 0)
          helper([], 0);
        return r;
    }
    

    Nested Collection Solution

    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;
        },
        addRoom: function(rooms, options) {
            return this.rooms.add(rooms, options);
        },
        removeRoom: function(rooms, options) {
            return this.rooms.remove(rooms, options);
        },
        createRoom: function(attributes, options) {
            return this.rooms.create(attributes, options);
        },
        getCombinations: function() {
            return cartesian(_.values(this.rooms.groupBy('level')));
        }
    });
    
    RoomModel = Backbone.Model.extend({});
    
    HotelCollection = Backbone.Collection.extend({
        model: HotelModel,
      getAllCombinations: function(){
        return this.map(function(hotel){
          return _.extend(hotel.toJSON(), {
            combinations: hotel.getCombinations()
          });
        });
      }
    });
    
    RoomCollection = Backbone.Collection.extend({
        model: RoomModel,
        getRoomsByHotelId: function(hotelId) {
            return this.where({
                hotelId: hotelId
            });
        }
    });
    

    Loading of the Separate JSON

    var hotels = new HotelCollection([], {
        url: 'hotels.json'
    });
    var rooms = new RoomCollection([], {
        url: 'rooms.json'
    });
    
    hotels.fetch({
        success: function() {
            rooms.fetch({
                success: function() {
                    hotels.each(function(hotel) {
                        hotel.addRoom(rooms.getRoomsByHotelId(hotel.id));
                    });
                    // all done here
                    var combos = hotels.getAllCombinations();
                    $(function() {
                        $('body').append('<pre>' + JSON.stringify(combos, null, 2) + '</pre>');
                    });
                }
            });
        }
    });
    

    hotels.json

    [{
      "id": 1,
        "name": "Hotel One"
    }, {
        "id": 2,
        "name": "Hotel Two"
    }, {
        "id": 3,
        "name": "Hotel Three"
    }]
    

    rooms.json

    [{
      "level": 1,
        "name": "Room A",
        "hotelId": 1
    }, {
        "level": 1,
        "name": "Room B",
        "hotelId": 1
    }, {
        "level": 2,
        "name": "Room A",
        "hotelId": 1
    }, {
        "level": 2,
        "name": "Room B",
        "hotelId": 1
    }, {
        "level": 1,
        "name": "Room A",
        "hotelId": 2
    }, {
        "level": 1,
        "name": "Room B",
        "hotelId": 2
    }, {
        "level": 2,
        "name": "Room A",
        "hotelId": 2
    }, {
      "level": 2,
        "name": "Room B",
        "hotelId": 2
    }, {
      "level": 1,
      "name": "Room A",
        "hotelId": 3
    }, {
      "level": 1,
      "name": "Room B",
      "hotelId": 3
    }, {
      "level": 1,
      "name": "Room C",
      "hotelId": 3
    }]
    
    0 讨论(0)
  • 2021-01-26 14:08

    First you should split your rooms list by hotels and levels:

    var rooms = _(allRooms.groupBy, "hotel_id");
    for (var hotelid in rooms)
        rooms[hotelid] = _.groupBy(rooms[hotelid], "level");
    

    The "combinations" you're looking for is the cartesian product of the levels (for each hotel). You can use this helper function for example. Use it like this:

    _.each(this.collection.models, function(hotel) {
        var levels = rooms[hotel.id];
        var combinations = cartesian(_.values(levels));
        // put them on the hotel
    });
    
    0 讨论(0)
提交回复
热议问题