Skip to content

Commit

Permalink
Merge pull request #80 from plumelo/feature/NEOV-320-refactor-instanc…
Browse files Browse the repository at this point in the history
…e-reuse

Realigns _elements when items change.
  • Loading branch information
Patrik Kullman authored May 1, 2019
2 parents 9eef07b + 04f8bd6 commit a13dc3e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
46 changes: 39 additions & 7 deletions cosmoz-data-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,16 +477,44 @@
index = items.findIndex(item => this._getItemId(item) === prevId);
}

// if still not found, remain on the selected index, but force re-render
// if still not found, remain on the selected index
if (index === -1) {
return this._updateSelected();
index = this.selected;
}
this._realignElements(index);
}

// update selected or force re-render if selected did not change
return this.selected === index ? this._updateSelected() : this.selected = index;
}

_realignElements(index) {
const elements = this._elements,
element = this._getElement(index),
item = this.items[index];
if (this.isIncompleteFn(item) || element.item === item) {
return;
}
const renderedElement = this._elements.find(el => !this.isIncompleteFn(el.item) && this._getItemId(el.item) === this._getItemId(item));
if (!renderedElement) {
return;
}
const elementIndex = elements.indexOf(element);
const renderedIndex = elements.indexOf(renderedElement);
if (elementIndex === renderedIndex) {
return;
}

renderedElement.item = item;
const instance = renderedElement.__instance,
props = Object.assign({ [this.as]: item }, this._getBaseProps(index));

Object.keys(props).forEach(key => instance._setPendingProperty(key, props[key]));
instance._flushProperties();

this.splice('_elements', renderedIndex, 1);
this.splice('_elements', elementIndex, 0, renderedElement);
}

/**
* Observes changed to `selected` property and
* updates related properties and the `selected` page.
Expand All @@ -510,13 +538,14 @@
this._updateHashForSelected(position);

const classes = element.classList,
animating = this.animating && previous != null && previous !== position,
prev = animating && this._getElement(previous);
animating = this.animating && previous != null && previous !== position;

if (!animating) {
this._elements.forEach(el => el.classList.remove('selected'));
}

const prev = animating && this._getElement(previous);

classes.toggle('in', !!this.animating);
classes.add('selected');

Expand Down Expand Up @@ -600,8 +629,11 @@
}

_getElement(index, _elements = this._elements) {
const elements = _elements && _elements.base || _elements;
return elements[index % (this.elementsBuffer || elements.length)];
const elements = _elements && _elements.base || _elements,
bufferLength = this.elementsBuffer || elements.length,
elementIndex = index % bufferLength;

return elements[elementIndex];
}

_getInstance(selectedElement) {
Expand Down
3 changes: 1 addition & 2 deletions test/spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,10 @@
flushRenderQueue(nav);
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 1somedata');

item.data = 'otherdata';
nav.items = [{id: 'a'}, {id: 'd'}, {id: 'e'}, item];
expect(nav.selected).to.equal(3);
flushRenderQueue(nav);
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 3otherdata');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 3somedata');
});

it('on `items` change, updates `selected` to match the last selected item, by id', () => {
Expand Down

0 comments on commit a13dc3e

Please sign in to comment.