Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure re-sort/filter always happens after array item set. Fixes #3626 #4942

Merged
merged 2 commits into from
Nov 22, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions lib/elements/dom-repeat.html
Original file line number Diff line number Diff line change
Expand Up @@ -456,13 +456,19 @@
}

__handleObservedPaths(path) {
if (this.__observePaths) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously the condition was only on this.__observePaths. Is there a case where this.__sortFn and this.__filterFn are both falsy, but this.__observePaths is truthy? In that case, this would regress, as the condition is no longer hit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the docs, observe (which sets __observePaths) is only relevant when using sort and/or filter so this seems ok.

path = path.substring(path.indexOf('.') + 1);
let paths = this.__observePaths;
for (let i=0; i<paths.length; i++) {
if (path.indexOf(paths[i]) === 0) {
this.__debounceRender(this.__render, this.delay);
return true;
// Handle cases where path changes should cause a re-sort/filter
if (this.__sortFn || this.__filterFn) {
if (!path) {
// Always re-render if the item iteself changed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/iteself/itself

this.__debounceRender(this.__render, this.delay);
} else if (this.__observePaths) {
// Otherwise, re-render if the path changed matches an observed path
path = path.substring(path.indexOf('.') + 1);
let paths = this.__observePaths;
for (let i=0; i<paths.length; i++) {
if (path.indexOf(paths[i]) === 0) {
this.__debounceRender(this.__render, this.delay);
}
}
}
}
Expand Down
53 changes: 53 additions & 0 deletions test/unit/dom-repeat.html
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,59 @@ <h4>x-repeat-chunked</h4>
});
});

test('item change refreshes sort and filter', function(done) {
// set filter fn
configured.$.repeater.sort = 'sortDesc';
configured.$.repeater.filter = 'filter2nd';
configured.$.repeater.render();
var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)');
assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect');
assert.equal(stamped[0].itemaProp, 'prop-3');
assert.equal(stamped[0].indexa, 0);
assert.equal(stamped[13].itemaProp, 'prop-1');
assert.equal(stamped[13].indexa, 1);

// Update observed prop to be in filter (set new object)
configured.set(['items', 1], Object.assign({}, configured.items[1], {prop: 'prop-0'}));
// avoid imperative/synchronous refresh() since that forces a full refresh
setTimeout(function() {
stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)');
assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect');
assert.equal(stamped[0].itemaProp, 'prop-3');
assert.equal(stamped[0].indexa, 0);
assert.equal(stamped[13].itemaProp, 'prop-1');
assert.equal(stamped[13].indexa, 1);
assert.equal(stamped[26].itemaProp, 'prop-0');
assert.equal(stamped[26].indexa, 2);

// Update observed prop back to be out of the filter (set new object)
configured.set(['items', 1], Object.assign({}, configured.items[1], {prop: 'prop-2'}));
setTimeout(function() {
var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)');
assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect');
assert.equal(stamped[0].itemaProp, 'prop-3');
assert.equal(stamped[0].indexa, 0);
assert.equal(stamped[13].itemaProp, 'prop-1');
assert.equal(stamped[13].indexa, 1);

// reset filter fn
configured.$.repeater.sort = null;
configured.$.repeater.filter = null;
configured.$.repeater.render();
stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)');
assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect');
assert.equal(stamped[0].itemaProp, 'prop-1');
assert.equal(stamped[0].indexa, 0);
assert.equal(stamped[13].itemaProp, 'prop-2');
assert.equal(stamped[13].indexa, 1);
assert.equal(stamped[26].itemaProp, 'prop-3');
assert.equal(stamped[26].indexa, 2);

done();
});
});
});

});

suite('nested un-configured dom-repeat in document', function() {
Expand Down