Question

I've encountered a problem I don't understand. I'm playing with Backbone and one of my initializer is called twice, one on purpose (when I instantiate my object) and it seems like it's called a second time from the constructor itself.

Here is my code :

class Views extends Backbone.Collection

    model: View

    initialize: ->
        _.bindAll @

class View extends Backbone.View

    initialize: ->
        _.bindAll @
        console.error 'Inner'

views = new Views
console.log 'Outer' 
views.add new View

When I run this code, Outer is displayed once while Inner is displayed 2 times. Here is the stack trace :

enter image description here

Any idea about this ?

Was it helpful?

Solution

When you initialize a collection, the first argument is the list of models to pre-populate it with.

class Models extends Backbone.Collection
    model: Model 

    initialize: (@rawModels) ->
        # CoffeeScript has the fat arrow that renders this unnecessary.
        # But it's something you should use as sparingly as possible.
        # Whatever. Not the time to get into that argument.
        _.bindAll @ 

        # At this point in time, all the models have been added to the
        # collection. Here, you add them again. IF the models have a
        # primary key attribute, this will detect that they already
        # exist, and not actually add them twice, but this is still
        # unnecessary.
        _.each @rawModels, @addItem

    # assuming this was a typo
    addItem: ( place ) -> @add new Model model

models = new Models json

Not directly related to your question, but hopefully helpful.

More directly related: don't create a collection of views. Collections are for storing Models. Backbone.View is not a type of Backbone.Model; they're separate. It doesn't really make sense -- you can just create an array of views -- and a lot of operations won't work right on that view collection.

Which is what's happening here.

When you call Backbone.Collection::add, it tries to see if what you're adding is a Backbone.Model. Since it's not, it assumes you're trying to add a JSON blob that it wants to turn into a Model. So it tries to do that...using its this.model class as a guide. But since that's View, it creates another one and adds that instead (not checking after the fact that it actually produced a Backbone.Model).

You can follow the call stack from add to set to _prepareModel, where the second View is instantiated.

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