Skip to content

Commit

Permalink
store.unregister now also accepts collections or a model type
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulUithol committed Feb 3, 2014
1 parent 4d0b705 commit 4113c69
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 12 deletions.
54 changes: 43 additions & 11 deletions backbone-relational.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@
update: function( model ) {
var coll = this.getCollection( model );

// Register a model if it isn't yet (which happens if it was created without an id).
if ( !coll.contains( model ) ) {
this.register( model );
}
Expand All @@ -500,22 +501,46 @@
},

/**
* Remove a 'model' from the store.
* @param {Backbone.RelationalModel} model
* @param {Backbone.Collection} [collection]
* @param {Object} [options]
* Unregister from the store: a specific model, a collection, or a model type.
* @param {Backbone.RelationalModel|Backbone.RelationalModel.constructor|Backbone.Collection} type
*/
unregister: function( model, collection, options ) {
this.stopListening( model );
unregister: function( type ) {
var coll,
models;

_.invoke( model.getRelations(), 'stopListening' );
if ( type instanceof Backbone.Model ) {
coll = this.getCollection( type );
models = [ type ];
}
else if ( type instanceof Backbone.Collection ) {
coll = this.getCollection( type.model );
models = _.clone( type.models );

This comment has been minimized.

Copy link
@philfreo

philfreo Feb 4, 2014

Collaborator

should you use type.clone() directly here since Backbone.Collection has a clone()?

This comment has been minimized.

Copy link
@PaulUithol

PaulUithol Feb 4, 2014

Author Owner

Ah, didn't stop to think that one could be proxied by Collection as well. Would be just a bit nicer indeed.

This comment has been minimized.

Copy link
@PaulUithol

PaulUithol Feb 24, 2014

Author Owner

Actually, that won't work here; coll.clone() would result in a new collection, while we just need an array of models here.

}
else {
coll = this.getCollection( type );
models = _.clone( coll.models );
}

var coll = this.getCollection( model );
if ( coll.get( model ) ) {
coll.remove( model, options );
_.each( models, function( model ) {
this.stopListening( model );
_.invoke( model.getRelations(), 'stopListening' );
}, this );


// If we've unregistered an entire store collection, reset the collection (which is much faster).
// Otherwise, remove each model one by one.
if ( _.contains( this._collections, type ) ) {
coll.reset( [] );
}
else {
coll.trigger( 'relational:remove', model, coll );
_.each( models, function( model ) {
if ( coll.get( model ) ) {
coll.remove( model );
}
else {
coll.trigger( 'relational:remove', model, coll );
}
}, this );
}
},

Expand All @@ -525,6 +550,12 @@
*/
reset: function() {
this.stopListening();

// Unregister each collection to remove event listeners
_.each( this._collections, function( coll ) {
this.unregister( coll );
}, this );

this._collections = [];
this._subModels = [];
this._modelScopes = [ exports ];
Expand Down Expand Up @@ -1478,6 +1509,7 @@
if ( !this._isInitialized && !this.isLocked() ) {
this.constructor.initializeModelHierarchy();

// Only register models that have an id. A model will be registered when/if it gets an id later on.
if ( newId || newId === 0 ) {
Backbone.Relational.store.register( this );
}
Expand Down
56 changes: 55 additions & 1 deletion test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,53 @@ $(document).ready(function() {
ok( !Backbone.Relational.store.getObjectByName( 'Person' ) );
});

test( "unregister", function() {
var animalStoreColl = Backbone.Relational.store.getCollection( Animal ),
animals = null,
animal = null;

// Single model
animal = new Animal( { id: 'a1' } );
ok( Backbone.Relational.store.find( Animal, 'a1' ) === animal );

Backbone.Relational.store.unregister( animal );
ok( Backbone.Relational.store.find( Animal, 'a1' ) === null );

animal = new Animal( { id: 'a2' } );
ok( Backbone.Relational.store.find( Animal, 'a2' ) === animal );

animal.trigger( 'relational:unregister', animal );
ok( Backbone.Relational.store.find( Animal, 'a2' ) === null );

ok( animalStoreColl.size() === 0 );

// Collection
animals = new AnimalCollection( [ { id: 'a3' }, { id: 'a4' } ] );
animal = animals.first();

ok( Backbone.Relational.store.find( Animal, 'a3' ) === animal );
ok( animalStoreColl.size() === 2 );

Backbone.Relational.store.unregister( animals );
ok( Backbone.Relational.store.find( Animal, 'a3' ) === null );

ok( animalStoreColl.size() === 0 );

// Store collection
animals = new AnimalCollection( [ { id: 'a5' }, { id: 'a6' } ] );
ok( animalStoreColl.size() === 2 );

Backbone.Relational.store.unregister( animalStoreColl );
ok( animalStoreColl.size() === 0 );

// Model type
animals = new AnimalCollection( [ { id: 'a7' }, { id: 'a8' } ] );
ok( animalStoreColl.size() === 2 );

Backbone.Relational.store.unregister( Animal );
ok( animalStoreColl.size() === 0 );
});

test( "`eventQueue` is unblocked again after a duplicate id error", 3, function() {
var node = new Node( { id: 1 } );

Expand Down Expand Up @@ -4588,12 +4635,15 @@ $(document).ready(function() {
});

var parents = new Parents();

parents.on('reset', function () {
var secs = (new Date() - start) / 1000;
console.log( 'data loaded in %s, addHasManyCount=%o, addHasOneCount=%o', secs, addHasManyCount, addHasOneCount );
});
parents.reset( preparedData );

//_.invoke( _.clone( parents.models ), 'destroy' );


/**
* Test 1
Expand All @@ -4604,12 +4654,15 @@ $(document).ready(function() {
var start = new Date();

var parents = new Parents();

parents.on('reset', function () {
var secs = (new Date() - start) / 1000;
console.log( 'data loaded in %s, addHasManyCount=%o, addHasOneCount=%o', secs, addHasManyCount, addHasOneCount );
});
parents.reset( data );

//_.invoke( _.clone( parents.models ), 'destroy' );


/**
* Test 2 (again)
Expand Down Expand Up @@ -4639,6 +4692,7 @@ $(document).ready(function() {
var secs = (new Date() - start) / 1000;
console.log( 'data loaded in %s, removeHasManyCount=%o, removeHasOneCount=%o', secs, removeHasManyCount, removeHasOneCount );

//_.invoke( _.clone( parents.models ), 'destroy' );

/**
* Test 1 (again)
Expand All @@ -4660,7 +4714,7 @@ $(document).ready(function() {
parents.remove( parents.models );

var secs = (new Date() - start) / 1000;
console.log( 'data loaded in %s, removeHasManyCount=%o, removeHasOneCount=%o', secs, removeHasManyCount, removeHasOneCount );
console.log( 'data removed in %s, removeHasManyCount=%o, removeHasOneCount=%o', secs, removeHasManyCount, removeHasOneCount );

console.log( 'registerCount=%o, unregisterCount=%o', registerCount, unregisterCount );
});
Expand Down

0 comments on commit 4113c69

Please sign in to comment.