Skip to content

Commit

Permalink
cleanup system/many-array
Browse files Browse the repository at this point in the history
* ensure shape is stable
* use tidier ES6 syntax when appropriate
  • Loading branch information
stefanpenner committed Nov 11, 2016
1 parent 1ca87a2 commit a986977
Showing 1 changed file with 79 additions and 86 deletions.
165 changes: 79 additions & 86 deletions addon/-private/system/many-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { assert } from "ember-data/-private/debug";
import { PromiseArray } from "ember-data/-private/system/promise-proxies";
import { _objectIsAlive } from "ember-data/-private/system/store/common";

var get = Ember.get;
var set = Ember.set;
const { get, set } = Ember;

/**
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
Expand Down Expand Up @@ -55,74 +54,25 @@ var set = Ember.set;
export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
init() {
this._super(...arguments);
this.currentState = Ember.A([]);
this.flushCanonical();
},

record: null,

canonicalState: null,
currentState: null,

length: 0,

objectAt(index) {
//Ember observers such as 'firstObject', 'lastObject' might do out of bounds accesses
if (!this.currentState[index]) {
return undefined;
}

return this.currentState[index].getRecord();
},

flushCanonical() {
let toSet = this.canonicalState;

//a hack for not removing new records
//TODO remove once we have proper diffing
let newRecords = this.currentState.filter(
// only add new records which are not yet in the canonical state of this
// relationship (a new record can be in the canonical state if it has
// been 'acknowleged' to be in the relationship via a store.push)
(internalModel) => internalModel.isNew() && toSet.indexOf(internalModel) === -1
);
toSet = toSet.concat(newRecords);
let oldLength = this.length;
this.arrayContentWillChange(0, this.length, toSet.length);
// It’s possible the parent side of the relationship may have been unloaded by this point
if (_objectIsAlive(this)) {
this.set('length', toSet.length);
}
this.currentState = toSet;
this.arrayContentDidChange(0, oldLength, this.length);
//TODO Figure out to notify only on additions and maybe only if unloaded
this.relationship.notifyHasManyChanged();
this.record.updateRecordArrays();
},
/**
`true` if the relationship is polymorphic, `false` otherwise.

@property {Boolean} isPolymorphic
@private
*/
isPolymorphic: false,

/**
/**
The loading state of this array
@property {Boolean} isLoaded
*/
isLoaded: false,
*/
this.isLoaded = false;
this.length = 0;

/**
The relationship which manages this array.
/**
Used for async `hasMany` arrays
to keep track of when they will resolve.
@property {ManyRelationship} relationship
@property {Ember.RSVP.Promise} promise
@private
*/
relationship: null,
*/
this.promise = null;

/**
/**
Metadata associated with the request for async hasMany relationships.
Example
Expand All @@ -136,7 +86,7 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
"id": 1,
"comment": "This is the first comment",
}, {
// ...
// ...
}],
"meta": {
Expand All @@ -152,16 +102,69 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
post.get('comments').then(function(comments) {
var meta = comments.get('meta');
// meta.page => 1
// meta.total => 5
// meta.page => 1
// meta.total => 5
});
```
@property {Object} meta
@public
*/
meta: null,
*/
this.meta = this.meta || null;

/**
`true` if the relationship is polymorphic, `false` otherwise.
@property {Boolean} isPolymorphic
@private
*/
this.isPolymorphic = this.isPolymorphic || false;


/**
The relationship which manages this array.
@property {ManyRelationship} relationship
@private
*/
this.relationship = this.relationship || null;

this.currentState = Ember.A([]);
this.flushCanonical();
},

objectAt(index) {
//Ember observers such as 'firstObject', 'lastObject' might do out of bounds accesses
if (!this.currentState[index]) {
return undefined;
}

return this.currentState[index].getRecord();
},

flushCanonical() {
let toSet = this.canonicalState;

//a hack for not removing new records
//TODO remove once we have proper diffing
let newRecords = this.currentState.filter(
// only add new records which are not yet in the canonical state of this
// relationship (a new record can be in the canonical state if it has
// been 'acknowleged' to be in the relationship via a store.push)
(internalModel) => internalModel.isNew() && toSet.indexOf(internalModel) === -1
);
toSet = toSet.concat(newRecords);
let oldLength = this.length;
this.arrayContentWillChange(0, this.length, toSet.length);
// It’s possible the parent side of the relationship may have been unloaded by this point
if (_objectIsAlive(this)) {
this.set('length', toSet.length);
}
this.currentState = toSet;
this.arrayContentDidChange(0, oldLength, this.length);
//TODO Figure out to notify only on additions and maybe only if unloaded
this.relationship.notifyHasManyChanged();
},
internalReplace(idx, amt, objects) {
if (!objects) {
objects = [];
Expand All @@ -179,9 +182,8 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {

//TODO(Igor) optimize
internalRemoveRecords(records) {
var index;
for (var i=0; i < records.length; i++) {
index = this.currentState.indexOf(records[i]);
for (let i=0; i < records.length; i++) {
let index = this.currentState.indexOf(records[i]);
this.internalReplace(index, 1);
}
},
Expand All @@ -195,23 +197,15 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
},

replace(idx, amt, objects) {
var records;
let records;
if (amt > 0) {
records = this.currentState.slice(idx, idx+amt);
this.get('relationship').removeRecords(records);
}
if (objects) {
this.get('relationship').addRecords(objects.map((obj) => obj._internalModel), idx);
this.get('relationship').addRecords(objects.map(obj => obj._internalModel), idx);
}
},
/**
Used for async `hasMany` arrays
to keep track of when they will resolve.
@property {Ember.RSVP.Promise} promise
@private
*/
promise: null,

/**
@method loadingRecordsCount
Expand Down Expand Up @@ -262,11 +256,10 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
@return {DS.PromiseArray} promise
*/
save() {
var manyArray = this;
var promiseLabel = "DS: ManyArray#save " + get(this, 'type');
var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
return manyArray;
}, null, "DS: ManyArray#save return ManyArray");
let manyArray = this;
let promiseLabel = 'DS: ManyArray#save ' + get(this, 'type');
let promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).
then(() => manyArray, null, 'DS: ManyArray#save return ManyArray');

return PromiseArray.create({ promise });
},
Expand All @@ -284,7 +277,7 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
var type = get(this, 'type');
var record;

assert("You cannot add '" + type.modelName + "' records to this polymorphic relationship.", !get(this, 'isPolymorphic'));
assert(`You cannot add '${type.modelName}' records to this polymorphic relationship.`, !get(this, 'isPolymorphic'));
record = store.createRecord(type.modelName, hash);
this.pushObject(record);

Expand Down

0 comments on commit a986977

Please sign in to comment.