ampersand-state
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -8,8 +8,3 @@ var _ = require('underscore'); | ||
options || (options = {}); | ||
this.cid = _.uniqueId('model'); | ||
// set collection/registry if passed in | ||
this.collection = options.collection; | ||
if (options.registry) this.registry = options.registry; | ||
if (options.parse) attrs = this.parse(attrs, options); | ||
this._initted = false; | ||
this._values = {}; | ||
@@ -20,7 +15,5 @@ this._initCollections(); | ||
this._events = {}; | ||
this._changed = {}; | ||
if (attrs) this.set(attrs, _.extend({silent: true, initial: true}, options)); | ||
this._changed = {}; | ||
this.initialize.apply(this, arguments); | ||
if (attrs && attrs[this.idAttribute] && this.registry) _.result(this, 'registry').store(this); | ||
this._initted = true; | ||
if (this.seal) Object.seal(this); | ||
@@ -31,29 +24,5 @@ } | ||
_.extend(Base.prototype, BBEvents, { | ||
idAttribute: 'id', | ||
namespaceAttribute: 'namespace', | ||
typeAttribute: 'modelType', | ||
// can be allow, ignore, reject | ||
extraProperties: 'ignore', | ||
// Get ID of model per configuration. | ||
// Should *always* be how ID is determined by other code. | ||
getId: function () { | ||
return this[this.idAttribute]; | ||
}, | ||
// Get namespace of model per configuration. | ||
// Should *always* be how namespace is determined by other code. | ||
getNamespace: function () { | ||
return this[this.namespaceAttribute]; | ||
}, | ||
// Get type of model per configuration. | ||
// Should *always* be how type is determined by other code. | ||
getType: function () { | ||
return this[this.typeAttribute]; | ||
}, | ||
// Stubbed out to be overwritten | ||
@@ -73,3 +42,3 @@ initialize: function () { | ||
serialize: function () { | ||
return this._getAttributes(false, true); | ||
return this.getAttributes({props: true}, true); | ||
}, | ||
@@ -83,4 +52,6 @@ | ||
var extraProperties = this.extraProperties; | ||
var triggers = []; | ||
var changing, previous, changes, newType, | ||
interpretedType, newVal, def, attr, attrs, silent, unset, currentVal, initial; | ||
interpretedType, newVal, def, attr, attrs, | ||
silent, unset, currentVal, initial; | ||
@@ -111,3 +82,3 @@ // Handle both `"key", value` and `{key: value}` -style arguments. | ||
if (!changing) { | ||
this._previousAttributes = this._getAttributes(true); | ||
this._previousAttributes = this.attributes; | ||
this._changed = {}; | ||
@@ -194,4 +165,2 @@ } | ||
var triggers = []; | ||
function gatherTriggers(key) { | ||
@@ -280,3 +249,3 @@ triggers.push(key); | ||
var val, changed = false; | ||
var old = this._changing ? this._previousAttributes : this._getAttributes(true); | ||
var old = this._changing ? this._previousAttributes : this.attributes; | ||
for (var attr in diff) { | ||
@@ -311,3 +280,3 @@ if (_.isEqual(old[attr], (val = diff[attr]))) continue; | ||
var self = this; | ||
_.each(this._getAttributes(true), function (val, key) { | ||
_.each(this.attributes, function (val, key) { | ||
self.unset(key, options); | ||
@@ -355,3 +324,9 @@ }); | ||
_getAttributes: function (includeSession, raw) { | ||
getAttributes: function (options, raw) { | ||
options || (options = {}); | ||
_.defaults(options, { | ||
session: false, | ||
props: false, | ||
derived: false | ||
}); | ||
var res = {}; | ||
@@ -361,3 +336,3 @@ var val, item, def; | ||
def = this._definition[item]; | ||
if (!def.session || (includeSession && def.session)) { | ||
if ((options.session && def.session) || (options.props && !def.session)) { | ||
val = (raw) ? this._values[item] : this[item]; | ||
@@ -368,2 +343,5 @@ if (typeof val === 'undefined') val = def.default; | ||
} | ||
if (options.derived) { | ||
for (item in this._derived) res[item] = this[item]; | ||
} | ||
return res; | ||
@@ -396,3 +374,3 @@ }, | ||
_verifyRequired: function () { | ||
var attrs = this._getAttributes(true); // should include session | ||
var attrs = this.attributes; // should include session | ||
for (var def in this._definition) { | ||
@@ -411,10 +389,12 @@ if (this._definition[def].required && typeof attrs[def] === 'undefined') { | ||
get: function () { | ||
return this._getAttributes(true); | ||
return this.getAttributes({props: true, session: true}); | ||
} | ||
}, | ||
derived: { | ||
all: { | ||
get: function () { | ||
var res = {}; | ||
for (var item in this._derived) res[item] = this._derived[item].fn.apply(this); | ||
return res; | ||
return this.getAttributes({ | ||
session: true, | ||
props: true, | ||
derived: true | ||
}); | ||
} | ||
@@ -426,3 +406,3 @@ } | ||
// appropriate getters/setters | ||
var createPropertyDefinition = function (object, name, desc, isSession) { | ||
function createPropertyDefinition(object, name, desc, isSession) { | ||
var def = object._definition[name] = {}; | ||
@@ -467,6 +447,6 @@ var type; | ||
return def; | ||
}; | ||
} | ||
// helper for creating derived property definitions | ||
var createDerivedProperty = function (modelProto, name, definition) { | ||
function createDerivedProperty(modelProto, name, definition) { | ||
var def = modelProto._derived[name] = { | ||
@@ -492,7 +472,7 @@ fn: _.isFunction(definition) ? definition : definition.fn, | ||
}); | ||
}; | ||
} | ||
// the extend method used to extend prototypes, maintain inheritance chains for instanceof | ||
// and allow for additions to the model definitions. | ||
var extend = function (protoProps) { | ||
function extend(protoProps) { | ||
var parent = this; | ||
@@ -555,2 +535,4 @@ var child; | ||
var toString = Object.prototype.toString; | ||
// Set a convenience property in case the parent's prototype is needed | ||
@@ -561,3 +543,3 @@ // later. | ||
return child; | ||
}; | ||
} | ||
@@ -614,2 +596,3 @@ // also expose data types in our export | ||
}; | ||
Base.extend = extend; | ||
@@ -616,0 +599,0 @@ |
{ | ||
"name": "ampersand-state", | ||
"description": "An observable, extensible state object with derived watchable properties.", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"author": "Henrik Joreteg <henrik@andyet.net>", | ||
@@ -6,0 +6,0 @@ "bugs": { |
@@ -152,32 +152,2 @@ /*jshint expr: true*/ | ||
test('custom id attribute', function (t) { | ||
var NewPerson = Person.extend({ | ||
props: { | ||
_id: 'number', | ||
ns: 'string' | ||
}, | ||
idAttribute: '_id', | ||
namespaceAttribute: 'ns' | ||
}); | ||
var person = new NewPerson({name: 'henrik', ns: 'group1', _id: 47}); | ||
t.equal(person.getId(), 47); | ||
t.equal(person.getNamespace(), 'group1'); | ||
t.end(); | ||
}); | ||
test('customizable `type` attribute', function (t) { | ||
var FirstModel = State.extend({ | ||
type: 'hello', | ||
typeAttribute: 'type' | ||
}); | ||
var SecondModel = State.extend({ | ||
modelType: 'second' | ||
}); | ||
var first = new FirstModel(); | ||
var second = new SecondModel(); | ||
t.equal(first.getType(), 'hello'); | ||
t.equal(second.getType(), 'second'); | ||
t.end(); | ||
}); | ||
test('everything should work with a property called `type`. Issue #6.', function (t) { | ||
@@ -184,0 +154,0 @@ var Model = State.extend({ |
@@ -452,18 +452,2 @@ var tape = require('tape'); | ||
test('should store models in the registry', function (t) { | ||
var foo = new Foo({ | ||
id: 1, | ||
firstName: 'roger', | ||
thing: 'meow' | ||
}); | ||
var blah = registry.lookup('foo', 1); | ||
t.strictEqual(foo.firstName, blah.firstName); | ||
t.strictEqual(foo, blah); | ||
foo.on('change', function () { | ||
t.ok(true); | ||
}); | ||
blah.firstName = 'blah'; | ||
t.end(); | ||
}); | ||
test('should be able to bind events even if sealed', function (t) { | ||
@@ -523,3 +507,2 @@ var SealedModel = State.extend({seal: true, props: {name: 'string'}}); | ||
get: function (val) { | ||
console.log('get', val); | ||
return val + 'crazy!'; | ||
@@ -526,0 +509,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54479
1302