Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defaults don't propagate through multiple levels of inheritance #1244

Closed
captncraig opened this issue Apr 24, 2012 · 3 comments
Closed

Defaults don't propagate through multiple levels of inheritance #1244

captncraig opened this issue Apr 24, 2012 · 3 comments

Comments

@captncraig
Copy link

Consider this code:

var parent = Backbone.Model.extend({defaults: {foo: 7}});
var instance1 = new parent();
console.log(instance1.get('foo')); //7
var child = parent.extend({defaults: {bar: 2}});
var instance2 = new child();
console.log(instance2.get('bar')); //2
console.log(instance2.get('foo')); //undefined

If you extend an existing model and provide new defaults, the original defaults are lost and don't operate as would be intended.
This could possibly be fixed by modifying extend to perform some basic merging with each member of the defaults for both the parent and the child.

@vincentbriglia
Copy link

var child = parent.extend({
    defaults: _.extend(parent.prototype.defaults, {
        bar: 2
    })
});

note that parent.extend and _.extend are not the same methods. Also see #276 why this has been declared as the Backbone way.

note that as defaults can be declared as a function you might need something like the following if you're inheriting multiple levels

var child = parent.extend({
    defaults: function () {
        var defaults = parent.prototype.defaults;
        var d = _.isFunction(defaults) ? defaults() : defaults;
        return _.extend(d, {
            bar: 2
        })
    }
});

@simenbrekken
Copy link

As a workaround you can assign a function to the defaults attribute and extend that:

Animal = Backbone.Model.extend({
    defaults: {
        eyes: 2,
        legs: 4
    }
});

Dinosaur = Animal.extend({
    defaults: function() {
        return _.extend({
            legs: 2,
            arms: 'too-short'
        }, _.result(Dinosaur.__super__, 'defaults'));
    },
});

var dog = new Animal();
console.log('Dog has:', dog.get('eyes'), 'eyes and', dog.get('legs'), 'legs');

var rex = new Dinosaur();
console.log('Rex has:', rex.get('eyes'), 'eyes and', rex.get('legs'), 'legs');

Will output:

Dog has 2 eyes and 4 legs
Rex has 2 eyes and 2 legs

@braddunbar
Copy link
Collaborator

Hi @captncraig. While defaults may not work work like it does in classical inheritance schemes, you can certainly make it behave similarly by declaring it as a function like @sbrekken suggests above. This has been discussed previously in #476 (and is still being discussed there). Would you mind directing further discussion there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants