Backbone 1.3.3 collection confusion demo
A collection's internal state keeps a reference to a removed model when `remove()`-ing that model as a response to `unset()`-ing its `id` attribute.
by David Bouman
HTML
<script src="https://rawgit.com/jashkenas/underscore/1.8.3/underscore-min.js"></script>
<script src="https://rawgit.com/jashkenas/backbone/1.3.3/backbone-min.js"></script>
<p>
<em>This fiddle is run against <a href="https://rawgit.com/jashkenas/backbone/1.3.3/backbone-min.js">Backbone 1.3.3</a>.</em>
</p>
<p>
Demonstrated below is the mixed-up internal state of the <code>collection</code> after the invocation of <code>model.unset('id')</code>:
</p>
<dl>
<dt><code>collection.models</code>:</dt>
<dd>
<textarea id="models"></textarea>
</dd>
<dt><code>collection._byId</code>:</dt>
<dd>
<textarea id="_byId"></textarea>
</dd>
<dt><code>collection.get( 'foo' )</code>:</dt>
<dd>
<textarea id="get-foo"></textarea>
</dd>
</dl>
CSS
code {
background: #eee;
border: solid 1px #ddd;
padding: .2em .3em;
margin: .1em 0 .2em;
display: inline-block;
vertical-align: middle;
}
textarea {
font-family: monospace;
}
JavaScript
var
MyView = Backbone.View.extend( {
initialize: function () {
this.model = new Backbone.Model( {
id: 'foo'
, foo: 'bar'
} );
this.collection = new Backbone.Collection( this.model );
this.listenTo( this.model, 'change:id', function ( model, id ) {
if ( id == null ) {
this.collection.remove( model );
}
} );
this.model.unset( 'id' );
$( '#models' ).val( JSON.stringify( this.collection.models ));
$( '#_byId' ).val( JSON.stringify( this.collection._byId ));
$( '#get-foo' ).val( JSON.stringify( this.collection.get( 'foo' )));
}
} )
, foo = new MyView()
;