Poni
Poni

Reputation: 11317

backbone.js Collection.add() doesn't `construct` (`initialize`) an object

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<head>
<script
    src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script
    src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
</head>
<body>

    <button id="cmd_create_event" name="cmd_create_event" type="button">Create
        a new `Event`</button>

    <script type="text/javascript">
        var EventModel = Backbone.Model.extend({
            initialize : function() {
                console.log("`Event` is initialized. id: " + this.cid);

                this.bind("change:status", function() {
                    console.log(this.get("status") + " is now the value for `status`");
                });

                this.bind("error", function(model, error) {
                    console.error(error);
                });
            },
            defaults : {
                "status" : 0
            },
            validate : function(attrs) {
                if (attrs.status <= 0)
                    return "invalid status";
            }
        });

        var EventList = Backbone.Collection.extend({
            initialize : function() {
                console.log("`EventList` is initialized");
            },
            model : EventModel,
            add : function(event) {
                console.log("`Event` added to `EventList`.");
            }
        });

        var EventView = Backbone.View.extend({});

        $(document).ready(function() {
            var event_list = new EventList();

            $("#cmd_create_event").click(function() {

                // GENERATION METHOD #1:
                /*var event = new EventModel();
                event.set({
                    status : 1
                });
                event_list.add(event);*/

                // GENERATION METHOD #2:
                event_list.add({
                    status : 1
                });

            });
        });
    </script>

</body>
</html>

In the above code there are two methods I'm using to add an EventModel to an EventList.

Method #1 does fire EventModel.initialize(), while Method #2 does not.

The docs says it's possible to add an object just like Method #2, so, why don't I get the object constructed as if I would new EventModel()? Quoting the docs:

If a model property is defined, you may also pass raw attributes objects, and have them be vivified as instances of the model.

Upvotes: 1

Views: 959

Answers (1)

Otto Allmendinger
Otto Allmendinger

Reputation: 28268

With the first method, you actually call the constructor of the model

var event = new EventModel();

With the second method, you just pass { status: 1 } to the EventList.add method you defined earlier, which only logs to console and doesn't do anything.

If you call

Backbone.Collection.prototype.add.call(this, event);

In your EventList.add method, Backbone creates an new model instance from the passed data and initialize() will be called (because you specified a model attribute when defining EventList).

Upvotes: 1

Related Questions