Reputation: 10613
I want to copy all attributes from backbone.js Model object to another if they are not undefined. It's a little like a child overriding the attributes of a parent. There will be some attributes of the child object which should be excluded from the entire process. This is what I have so far:
function inherit(parent, child) {
var childAttributes = Object.keys(child.attributes);
// Don't involve these attributes in any way, they're special.
attributes = _.without(attributes, ['specialCase1', 'specialCase2', 'specialCase3']);
// This array will store undefined child attributes
var undefChildAttributes = new Array();
for (i in attributes) {
var attr = attributes[i]; // Get attribute name
var value = child.get(attr); // ... and value
var type = RealTypeOf(value); // ... and type
if (type == 'undefined') {
undefChildAttributes.push(attr);
}
}
// Update the child attributes array to not include undefined any attributes
attributes = _.without(attributes, undefChildAttributes);
// Copy any attributes from child to parent
// ------------------ PROBLEM AREA ------------------
for (var m=0; m<attributes.length; m++) {
var attr = attributes[m]; // Attribute to copy
// I want to use _.extends in some way here, maybe like:
_.extends(parent, child[attr]);
}
}
I'm stuck at the point of how to copy the attribute into the parent. The only way I have atm is a hack:
if (type == 'string') {
eval('var o = {' + attr + ':"' + child.get(attr) + '"};');
} else {
eval('var o = {' + attr + ':' + child.get(attr) + '};');
}
parent.set(o);
Upvotes: 3
Views: 3858
Reputation: 33344
You can avoid eval
by using the bracket notation:
var o = {};
o[attr] = child.get(attr);
parent.set(o);
And my take on your code, if I got it right
function inherit(parent, child) {
var attributes = child.toJSON(),
keepkeys = _.keys(attributes);
// remove special cases
keepkeys = _.without(keepkeys, 'specialCase1', 'specialCase2');
// or keepkeys = _.difference(keepkeys, ['specialCase1', 'specialCase2']);
// remove undefined values
keepkeys = _.filter(keepkeys, function (key) {
return typeof(attributes[key])!=="undefined";
});
// with underscore>=1.3.3
var result = _.pick(attributes, keepkeys);
// with underscore<1.3.3
// var result = {};
// _.each(keepkeys, function (key) {
// result[key] = attributes[key];
// });
parent.set(result);
}
var P = new Backbone.Model();
var C = new Backbone.Model({
copy1: "c1",
specialCase1: "do not copy",
undefkey: undefined
});
inherit(P, C);
console.log(P.toJSON());
And a Fiddle http://jsfiddle.net/tdCEF/
Upvotes: 5