|
392 | 392 | // Override Backbone's objects .extend... |
393 | 393 | [ 'Model', 'Collection', 'View', 'Router', 'History' ].forEach( function( name ){ |
394 | 394 | var BackboneType = Backbone[ name ]; |
395 | | - Object.extend.attach( BackboneType ); |
| 395 | + if( BackboneType ) Object.extend.attach( BackboneType ); |
396 | 396 | }); |
397 | 397 |
|
398 | 398 | Nested.Class = Object.extend.Class; |
|
627 | 627 | if( this.__events ) model.listenTo( value, this.__events ); |
628 | 628 | } |
629 | 629 |
|
630 | | - model.trigger( 'replace:' + name, model, prev, value ); |
| 630 | + trigger3( model, 'replace:' + name, model, value, prev ); |
631 | 631 | } |
632 | 632 |
|
633 | 633 | return value; |
|
824 | 824 | properties : { |
825 | 825 | id : { |
826 | 826 | get : function(){ |
827 | | - var name = this.idAttribute; // TODO: add get event handling for id attr |
828 | | - return name === 'id' ? this.attributes.id : this[ this.idAttribute ]; |
| 827 | + var name = this.idAttribute; |
| 828 | + |
| 829 | + // TODO: get hook doesn't work for idAttribute === 'id' |
| 830 | + return name === 'id' ? this.attributes.id : this[ name ]; |
829 | 831 | }, |
830 | 832 |
|
831 | 833 | set : function( value ){ |
|
1103 | 1105 |
|
1104 | 1106 | // Compile optimized constructor function for efficient deep copy of JSON literals in defaults. |
1105 | 1107 | _.each( attrSpecs, function( attrSpec, name ){ |
1106 | | - if( attrSpec.value !== undefined ){ |
| 1108 | + if( attrSpec.value === undefined && attrSpec.type ){ |
| 1109 | + // if type with no value is given, create an empty object |
| 1110 | + init[ name ] = attrSpec; |
| 1111 | + statements.push( 'this.' + name + '=i.' + name + '.create( o );' ); |
| 1112 | + } |
| 1113 | + else{ |
1107 | 1114 | // If value is given, type casting logic will do the job later, converting value to the proper type. |
1108 | 1115 | if( isValidJSON( attrSpec.value ) ){ |
1109 | 1116 | // JSON literals must be deep copied. |
1110 | 1117 | statements.push( 'this.' + name + '=' + JSON.stringify( attrSpec.value ) + ';' ); |
1111 | 1118 | } |
| 1119 | + else if( attrSpec.value === undefined ){ |
| 1120 | + // handle undefined value separately. Usual case for model ids. |
| 1121 | + statements.push( 'this.' + name + '=undefined;' ); |
| 1122 | + } |
1112 | 1123 | else{ |
1113 | 1124 | // otherwise, copy value by reference. |
1114 | 1125 | refs[ name ] = attrSpec.value; |
1115 | 1126 | statements.push( 'this.' + name + '=r.' + name + ';' ); |
1116 | 1127 | } |
1117 | | - } |
1118 | | - else{ |
1119 | | - // if type with no value is given, create an empty object |
1120 | | - if( attrSpec.type ){ |
1121 | | - init[ name ] = attrSpec; |
1122 | | - statements.push( 'this.' + name + '=i.' + name + '.create( o );' ); |
1123 | | - } |
1124 | 1128 |
|
1125 | 1129 | } |
1126 | 1130 | }); |
|
1231 | 1235 |
|
1232 | 1236 | getModelIds : function(){ return _.pluck( this.models, 'id' ); } |
1233 | 1237 | },{ |
| 1238 | + // Cache for subsetOf collection subclass. |
| 1239 | + __subsetOf : null, |
1234 | 1240 | defaults : function( attrs ){ |
1235 | 1241 | return this.prototype.model.extend({ defaults : attrs }).Collection; |
| 1242 | + }, |
| 1243 | + extend : function(){ |
| 1244 | + // Need to subsetOf cache when extending the collection |
| 1245 | + var This = Backbone.Collection.extend.apply( this, arguments ); |
| 1246 | + This.__subsetOf = null; |
| 1247 | + return This; |
1236 | 1248 | } |
1237 | 1249 | }); |
1238 | 1250 |
|
|
1273 | 1285 | } |
1274 | 1286 | } )( this, this.name, this.get ); |
1275 | 1287 | } |
1276 | | - else Nested.options.Type.prototype.createPropertySpec.call( this ); |
| 1288 | + else return Nested.options.Type.prototype.createPropertySpec.call( this ); |
1277 | 1289 | }, |
1278 | 1290 |
|
1279 | 1291 | cast : function( value, options, model, name ){ |
|
1471 | 1483 | }; |
1472 | 1484 |
|
1473 | 1485 | return function( masterCollection ){ |
1474 | | - var SubsetOf = this._subsetOf || ( this._subsetOf = this.extend( refsCollectionSpec ) ); |
| 1486 | + var SubsetOf = this.__subsetOf || ( this.__subsetOf = this.extend( refsCollectionSpec ) ); |
1475 | 1487 | var getMaster = parseReference( masterCollection ); |
1476 | 1488 |
|
1477 | 1489 | return Nested.options({ |
|
1517 | 1529 | var self = this; |
1518 | 1530 |
|
1519 | 1531 | _.each( this.attributes, function( element, name ){ |
| 1532 | + if( !element ) return; |
1520 | 1533 | var fetch = element.fetch; |
1521 | 1534 | if( fetch ){ |
1522 | 1535 | element.fetch = function(){ |
|
0 commit comments