Skip to content

Commit 9b16ddf

Browse files
authored
Merge pull request #17 from richmolj/master
Define attributes on instance, not prototype
2 parents e6628a4 + a20746f commit 9b16ddf

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/attribute.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export default class Attribute {
2121
this._eachAttribute(klass, (attr) => {
2222
klass.attributeList[attr.name] = attr;
2323
let descriptor = attr.descriptor();
24-
Object.defineProperty(klass.prototype, attr.name, descriptor);
2524
let instance = new klass();
2625

2726
let decorators = instance['__attrDecorators'] || [];

src/model.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ export default class Model {
166166
}
167167

168168
constructor(attributes?: Object) {
169+
this._initializeAttributes();
169170
this.attributes = attributes;
170171
this._originalAttributes = cloneDeep(this.attributes);
171172
this._originalRelationships = this.relationshipResourceIdentifiers(Object.keys(this.relationships));
@@ -266,6 +267,10 @@ export default class Model {
266267
return dc.checkRelation(relationName, relatedModel);
267268
}
268269

270+
dup() : Model {
271+
return cloneDeep(this);
272+
}
273+
269274
destroy() : Promise<any> {
270275
let url = this.klass.url(this.id);
271276
let verb = 'delete';
@@ -297,6 +302,15 @@ export default class Model {
297302
});
298303
}
299304

305+
// Define getter/setters and set defaults
306+
private _initializeAttributes() {
307+
for (let key in this.klass.attributeList) {
308+
let attr = this.klass.attributeList[key];
309+
Object.defineProperty(this, attr.name, attr.descriptor());
310+
this[key] = this[key]; // set defaults
311+
}
312+
}
313+
300314
private _writeRequest(requestPromise : Promise<any>, callback: Function) : Promise<any> {
301315
return new Promise((resolve, reject) => {
302316
requestPromise.catch((e) => { throw(e) });

test/unit/attributes-test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { sinon, expect } from '../test-helper';
2-
import { Person } from '../fixtures';
2+
import { Person, Author } from '../fixtures';
33

44
describe('Model attributes', function() {
55
it('supports direct assignment', function() {
@@ -29,6 +29,18 @@ describe('Model attributes', function() {
2929
expect(person.firstName).to.eq('Jane');
3030
});
3131

32+
it('sets attributes properties on the instance', function() {
33+
let person = new Person();
34+
expect(person.hasOwnProperty('firstName')).to.eq(true);
35+
expect(Object.getOwnPropertyDescriptor(person, 'firstName'))
36+
.to.not.eq(undefined);
37+
});
38+
39+
it('defaults hasMany before the getter is called', function() {
40+
let author = new Author();
41+
expect(author.relationships['books']).to.deep.eq([])
42+
});
43+
3244
// Without this behavior, the API could add a backwards-compatible field,
3345
// and this object might blow up.
3446
describe('when passed an invalid attribute in constructor', function() {

0 commit comments

Comments
 (0)