Skip to content

Commit

Permalink
reduce number of components searched (#149)
Browse files Browse the repository at this point in the history
This commit has 2 goals:

1) A small refactoring of the getValue method to split out the
multiple/single value cases.
2) Decrease the number of elements `_getValue` searches through if
possible. `Array.prototype.find` stops iterating on the array when the
callback returns truthy. `options` is an `Ember.A` which means it should
polyfill the `Array.prototype.find` method.

Say you have an array like:

```javascript
const values = [1, 2, 3];
```

If we're looking for the value `2`, we only want to search the array two
times, because the number 2 is found on the second iteration.

This reduces the amount of work we have to do on larger arrays because
we can bail if the element is found early. While this doesn't matter
much on an array of 5, it can matter more with bigger arrays especially
since we're querying the DOM.
  • Loading branch information
fivetanley authored and Robdel12 committed Sep 14, 2016
1 parent 9e4f871 commit c575bf3
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions addon/components/x-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const {
computed,
} = Ember;

const isSelectedOption = (option) => option.$().is(':selected');

/**
* Wraps a native <select> element so that it can be object and
* binding aware. It is used in conjuction with the
Expand Down Expand Up @@ -114,16 +116,30 @@ export default Ember.Component.extend({
* @return {Array|Object} the current selection
*/
_getValue() {
let options = this.get('options').filter(function(option) {
return option.$().is(':selected');
});
return this.get('multiple') ? this._findMultipleValues() : this._findSingleValue();
},

if (this.get('multiple')) {
return Ember.A(options).mapBy('value');
} else {
let option = options[0];
return option ? option.get('value') : null;
}
/**
* Finds all selected values from all `x-option`
* children. Used when this.get('multiple') === true
*
* @private
* @return {Array} all the values from selected x-options
*/
_findMultipleValues() {
return this.get('options').filter(isSelectedOption).map(option => option.get('value'));
},

/**
* Returns the value of the first selected `x-option`.
* Used when `this.get('multiple') !== true`
*
* @private
* @return {Object} the value of the first select `x-option`, or null
*/
_findSingleValue() {
const selectedValue = this.get('options').find(isSelectedOption);
return selectedValue ? selectedValue.get('value') : null;
},

/**
Expand Down

0 comments on commit c575bf3

Please sign in to comment.