Question

I am trying to implement a simple app which is able to get a collection for a given object_id.
The GET response from the server looks like this:

[
    {object_id: 1, text: "msg1"}, 
    {object_id: 1, text: "msg2"}, 
    {object_id: 1, text: "msg3"},
    .......
]

My goal is:
render a collection when the user choose an object_id.

The starting point of my code is the following:

this.options = {object_id: 1};
myView = new NeView(_.extend( {el:this.$("#myView")} , this.options));

My question is:
* What is the best way:
1) to set the object_id value in the MyModel in order to
2) trigger the fetch in MyCollection and then
3) trigger the render function in myView?*
or to active my goal?


P.S:

My basic code looks like this:

// My View
define([
    "js/collections/myCollection",
    "js/models/myFeed"
], function (myCollection, MyModel) {
    var MyView = Backbone.View.extend({

        initialize: function () {

            var myModel = new MyModel();

            _.bindAll(this, "render");

            myModel.set({
                object_id: this.options.object_id
            }); // here I get an error: Uncaught TypeError: Object function (){a.apply(this,arguments)} has no method 'set'
        }
    });

    return MyView;
});

// MyCollection
define([
    "js/models/myModel"
], function (MyModel) {

    var MyCollection = Backbone.Collection.extend({

        url: function () {
            return "http://localhost/movies/" + myModel.get("object_id");
        }
    });

    return new MyCollection
});

//MyModel
define([
], function () {

    var MyModel = Backbone.Model.extend({
    });

    return MyModel
});
Was it helpful?

Solution

There's a few, if not fundamentally things wrong with your basic understanding of Backbone's internals.

First off, define your default model idAttribute, this is what identifies your key you lookup a model with in a collection

//MyModel
define([
], function () {

    var MyModel = Backbone.MyModel.extend({
        idAttribute: 'object_id'
    });

    return MyModel
});

in your collection, there is no need to define your URL in the way you defined it, there are two things you need to change, first is to define the default model for your collection and second is to just stick with the base url for your collection

// MyCollection
define([
    "js/models/myModel"
], function (MyModel) {

    var MyCollection = Backbone.MyCollection.extend({
        model: MyModel, // add this
        url: function () {
            return "http://localhost/movies
        }
    });

    return MyCollection // don't create a new collection, just return the object
});

and then your view could be something along these lines, but is certainly not limited to this way of implementing

// My View
define([
    "js/collections/myCollection",
    "js/models/myFeed"
], function (MyCollection, MyModel) {
    var MyView = Backbone.View.extend({

        tagName: 'ul',

        initialize: function () {
            this.collection = new MyCollection();
            this.collection.on('add', this.onAddOne, this);
            this.collection.on('reset', this.onAddAll, this);
        },

        onAddAll: function (collection, options)
        {
            collection.each(function (model, index) {
                that.onAddOne(model, collection);
            });
        },

        onAddOne: function (model, collection, options)
        {
            // render out an individual model here, either using another Backbone view or plain text
            this.$el.append('<li>' + model.get('text') + '</li>');
        }

    });

    return MyView;
});

Take it easy and go step by step

I would strongly recommend taking a closer look at the exhaustive list of tutorials on the Backbone.js github wiki: https://github.com/documentcloud/backbone/wiki/Tutorials%2C-blog-posts-and-example-sites ... try to understand the basics of Backbone before adding the additional complexity of require.js

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top