diff --git a/README.md b/README.md index 9f594d7..95d83b3 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,65 @@ var people = new AmpersandCollection([{ name: 'phil' }, { name: 'bob' }, { name: }); ``` +### postInitialize `collection.postInitialize()` + +If you have defined a `postInitialize` function for your subclass of Collection, it will be invoked at creation time, just after it's parent or (parent-)collection `initialize` functions has been triggerd. + +``` +var State = require('ampersand-state'); +var Collection = require('ampersand-collection'); + +var Widget = State.extend({ + props: { + name: 'string', + funLevel: 'number' + }, + postInitialize: function() { + console.log('code to run just AFTER this.parent.initialize has been invoked'); + } +}); + +var Hat = State.extend({ + props: { + color: 'string' + }, + postInitialize: function() { + console.log('code to run just AFTER this.parent.initialize has been invoked'); + } +}); + +var WidgetCollection = Collection.extend({ + model: Widget, + postInitialize: function() { + console.log('code to run just AFTER this.parent.initialize has been invoked'); + } +}); + +var Person = AmpersandState.extend({ + props: { + name: 'string' + }, + children: { + hat: Hat + } + collections: { + widgets: WidgetCollection + } +}); + +var me = new Person({ + name: 'Bob', + hat: { + color: 'red' + } + widgets: [ + { name: 'music', funLevel: 10 }, + { name: 'coding', funLevel: 10 } + ] +}); + +``` + ### mainIndex `collection.mainIndex` Specify which property the collection should use as the main index (and unique identifier) for the models/objects it holds. This is the property that [`get`](#ampersand-collection-get) uses to retrieve models, and what `add`, `set`, and `remove` uses to determine whether a collection already contains a model or not. diff --git a/ampersand-collection.js b/ampersand-collection.js index 88a568e..cbaf406 100644 --- a/ampersand-collection.js +++ b/ampersand-collection.js @@ -17,11 +17,19 @@ function Collection(models, options) { this._reset(); this.initialize.apply(this, arguments); if (models) this.reset(models, assign({silent: true}, options)); + if (options.postInit !== false) { + this.forEach(function(model) { + if(model.postInitialize) model.postInitialize.apply(model); + }); + this.postInitialize.apply(this); + } } assign(Collection.prototype, AmpersandEvents, { initialize: function () {}, + postInitialize: function () {}, + isModel: function (model) { return this.model && model instanceof this.model; }, diff --git a/test/main.js b/test/main.js index bf0f9d7..cc96dfd 100644 --- a/test/main.js +++ b/test/main.js @@ -522,3 +522,42 @@ test('Collection should rethrow change events on a model', function (t) { model.name = 'shmoe'; }); + + +test('Add a postInitialize-functionality over States and Collections, Children and subCollections', function (t) { + var result = []; + /**** Model Test *****/ + var MyModel = State.extend({ + props: { + val: 'number' + }, + initialize: function() { + result.push(this.val); + }, + postInitialize: function() { + result.push(this.val); + } + }); + + /**** Collection Test *****/ + var MyCollection = Collection.extend({ + model: MyModel, + initialize: function() { + result.push(-1); + }, + postInitialize: function() { + result.push(-1); + } + }); + + var a = new MyCollection([{ + val: 0 + }, { + val: 1 + }, { + val: 2 + }]); + t.deepEqual(result, [ -1, 0 , 1 ,2, 0, 1, 2, -1 ]); + + t.end(); +});