Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Backbone.js populate collection of models

Here is what I have so far:

var Item = Backbone.Model.extend({
    defaults: {
        id: 0,
        pid: 0,
        t: null,
        c: null
    },
    idAttribute: 'RootNode_', // what should this be ???
    url: 'page.php'
});

var ItemList = Backbone.Collection.extend({
    model: Item,
    url: 'page.php',
    parse: function(data) {
        alert(JSON.stringify(data)); // returns a list of json objects, but does nothing with them ???
    }
});

var ItemView = Backbone.View.extend({
    initialize: function() {
        this.list = new ItemList();
        this.list.bind('all', this.render, this);
        this.list.fetch();
    },
    render: function() {
        // access this.list ???
    }
});

var view = new ItemView();

Current (expected) json response:

{
    "RootElem_0":{"Id":1,"Pid":1,"T":"Test","C":"Blue"},
    "RootElem_1":{"Id":2,"Pid":1,"T":"Test","C":"Red"},
    "RootElem_2":{"Id":3,"Pid":1,"T":"Test2","C":"Money"}
}

This successfully polls page.php and the backend acts on $_SERVER['REQUEST_METHOD'] and returns the required information, however I don't know why the collection is not filled.

In the parse function of ItemList it properly shows me all the output, but it does nothing with it.

I left some comments in the code for some more precise questions, but the main question is why doesn't the collection populate with the obviously received data?

like image 487
Nahydrin Avatar asked Jan 17 '23 12:01

Nahydrin


2 Answers

Modify your parse method to:

parse: function(response){
   var parsed = [];
   for(var key in response){
      parsed.push(response[key]);
   }
   return parsed;
}

To follow conventions, change list inside ItemView to model. Also in render():

render: function() {
    var template = _.template("<div>some template</div>");
    this.model.each(function(item){ 
        this.$el.append(template(item.toJSON()));
    }, this);
    return this;
}
like image 149
driangle Avatar answered Jan 20 '23 13:01

driangle


The parse method you're supposed to be returning the data after doing whatever necessary parsing is required for it.

The common use case for parse would be if you're sending back an object of a form like:

{ "id" : "NaN", "tasks": [ *all your models in a list here *] }

then you'd use parse like so:

parse: function (data) {
    return data.tasks
}

Backbone then handles the rest.

Is there a particular reason why you're sending the data back in that dictionary format? It's not exactly clear how you intend to map that to each model of the collection. Is the key irrelevant? if so, you should be passing back a list of the objects in the values.(Although see note at bottom). If not, and you want to attach it to the models, it should be moved to the object you're using as a value and send back a list.

* Note: Don't actually send back a JSON list bare. There is an exploit for GET requests that relies on lists being valid javascript on their own, where a malicious site can use the Array object and override it to use a script tag to your API to use the users credentials to pull down whatever information is available in that call. Instead, when wanting to send back a list you should use something like this:

{ result: [*list here*] }

Then you just use the parse method above to extract the list.

like image 44
Jeff Bain Avatar answered Jan 20 '23 13:01

Jeff Bain