Last active
August 29, 2015 13:58
-
-
Save cibernox/9950325 to your computer and use it in GitHub Desktop.
First approach to a filterPropertyBetween CP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(exports){ | |
exports.computed = {}; | |
/** | |
* Returns an arrayComputed property that filters the elements in the `dependentKey` | |
* that have its `propertyKey` between (inclusive) the values in `startKey` and `endKey`. | |
* It reacts to additions to changes in the `dependentKey`, `startKey` and `endKey`. | |
* | |
* Right now it assumes that the array in the dependentKey is sorted and preserves | |
* that sorting. | |
* | |
* TODO: React to removed items in the property key | |
* TODO: Tests. | |
* | |
* @param {String} dependentKey The name of the property with the collection to be filtered | |
* @param {String} propertyKey The name of the property to be between the bounds (inclusive) | |
* @param {String} startKey The name of the property with the start of the range. | |
* @param {String} endKey The name of the property with the end of the range. | |
* @return {Array} | |
*/ | |
exports.computed.filterPropertyBetween = function(dependentKey, propertyKey, startKey, endKey){ | |
var get = Ember.get; | |
// Remove elements of the beginning of the array. | |
var shiftItems = function(sourceArray, items, rangeStart, rangeEnd){ | |
var result = Ember.A(), item, i, value; | |
for (i = 0; i < items.length; i++){ | |
item = items.objectAt(i); | |
value = get(item, propertyKey); | |
if (value >= rangeStart) break; | |
if (value <= rangeEnd) result.push(item); | |
} | |
items.removeObjects(result); | |
}; | |
// Add elements at the beginning of the array | |
var unshiftItems = function(sourceArray, items, rangeStart, rangeEnd){ | |
var firstAlreadyIncludedIndex = sourceArray.length, | |
result = Ember.A(), | |
item, i, value; | |
if (items[0]){ | |
firstAlreadyIncludedIndex = sourceArray.indexOf(items[0]); | |
} | |
for (i = firstAlreadyIncludedIndex - 1; i >= 0; i--){ | |
item = sourceArray[i]; | |
value = get(item, propertyKey); | |
if (value < rangeStart) break; | |
if (value < rangeEnd) result.insertAt(0, item); | |
} | |
items.unshiftObjects(result); | |
}; | |
// Remove elements at the end of the array | |
var popItems = function(sourceArray, items, rangeStart, rangeEnd){ | |
var result = Ember.A(), item, i, value; | |
for (i = items.length -1; i >= 0; i--){ | |
item = items[i]; | |
value = get(item, propertyKey); | |
if (value <= rangeEnd) break; | |
if (value >= rangeStart) result.insertAt(0, item); | |
} | |
items.removeObjects(result); | |
}; | |
// Add elements at the end of the array | |
var pushItems = function(sourceArray, items, rangeStart, rangeEnd){ | |
var lastAlreadyIncludedIndex = sourceArray.indexOf(items.get('lastObject')), | |
length = sourceArray.length, | |
result = Ember.A(), | |
item, i, value; | |
for (i = lastAlreadyIncludedIndex + 1; i < length; i++){ | |
item = sourceArray[i]; | |
value = get(item, propertyKey); | |
if (value > rangeEnd) break; | |
if (value > rangeStart) result.push(item); | |
} | |
items.pushObjects(result); | |
}; | |
var initFn = function(array, changeMeta, instanceMeta){ | |
instanceMeta[startKey] = this.get(startKey); | |
instanceMeta[endKey] = this.get(endKey); | |
var rangeStartChanged = function(){ | |
var newRangeStart = get(this, startKey), | |
newRangeEnd = get(this, endKey); | |
if (newRangeStart > instanceMeta[startKey]){ | |
shiftItems(get(this, dependentKey), array, newRangeStart, newRangeEnd); | |
} else { | |
unshiftItems(get(this, dependentKey), array, newRangeStart, newRangeEnd); | |
} | |
instanceMeta[startKey] = newRangeStart; | |
}; | |
var rangeEndChanged = function(){ | |
var newRangeStart = get(this, startKey), | |
newRangeEnd = get(this, endKey); | |
if (newRangeEnd < instanceMeta[endKey]){ | |
popItems(get(this, dependentKey), array, newRangeStart, newRangeEnd); | |
} else { | |
pushItems(get(this, dependentKey), array, newRangeStart, newRangeEnd); | |
} | |
instanceMeta[endKey] = newRangeEnd; | |
}; | |
Ember.addObserver(this, startKey, function(object){ | |
Ember.run.once(object, rangeStartChanged); | |
}); | |
Ember.addObserver(this, endKey, function(object){ | |
Ember.run.once(object, rangeEndChanged); | |
}); | |
}; | |
return Ember.arrayComputed(dependentKey + '.@each.' + propertyKey, { | |
initialize: initFn, | |
addedItem: function(array, item, changeMeta, instanceMeta) { | |
var performedAt = item.get(propertyKey), | |
rangeStart = this.get(startKey), | |
rangeEnd = this.get(endKey); | |
if (performedAt >= rangeStart && performedAt <= rangeEnd) { | |
array.insertAt(Math.min(changeMeta.index, array.length), item); | |
} | |
return array; | |
} | |
}); | |
}; | |
})(App) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment