Skip to content

Commit

Permalink
fix: Repeat/map now always rerender. Resolves #179.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelketek authored and klebba committed Oct 8, 2024
1 parent e60005b commit ce67bc9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 7 deletions.
60 changes: 60 additions & 0 deletions test/test-template-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,36 @@ describe('html updaters', () => {
container.remove();
});

it('repeat re-runs each time', () => {
const getTemplate = ({ items, lookup }) => {
return html`
<div>
<ul id="target">
${repeat(items, item => item.id, item => {
return html`<li id="${item.id}">${lookup?.[item.id]}</li>`;
})}
</ul>
</div>
`;
};
const container = document.createElement('div');
document.body.append(container);
const items = [{ id: 'a' }, { id: 'b'}, { id: 'c' }];
let lookup = { a: 'foo', b: 'bar', c: 'baz' };
render(container, getTemplate({ items, lookup }));
assert(container.querySelector('#target').childElementCount === 3);
assert(container.querySelector('#a').textContent === 'foo');
assert(container.querySelector('#b').textContent === 'bar');
assert(container.querySelector('#c').textContent === 'baz');
lookup = { a: 'fizzle', b: 'bop', c: 'fuzz' };
render(container, getTemplate({ items, lookup }));
assert(container.querySelector('#target').childElementCount === 3);
assert(container.querySelector('#a').textContent === 'fizzle');
assert(container.querySelector('#b').textContent === 'bop');
assert(container.querySelector('#c').textContent === 'fuzz');
container.remove();
});

it('map', () => {
const getTemplate = ({ items }) => {
return html`
Expand Down Expand Up @@ -592,6 +622,36 @@ describe('html updaters', () => {
container.remove();
});

it('map: re-renders each time', () => {
const getTemplate = ({ items, lookup }) => {
return html`
<div>
<ul id="target">
${map(items, item => item.id, item => {
return html`<li id="${ item.id }">${ lookup?.[item.id] }</li>`;
})}
</ul>
</div>
`;
};
const container = document.createElement('div');
document.body.append(container);
const items = [{ id: 'a' }, { id: 'b'}, { id: 'c' }];
let lookup = { a: 'foo', b: 'bar', c: 'baz' };
render(container, getTemplate({ items, lookup }));
assert(container.querySelector('#target').childElementCount === 3);
assert(container.querySelector('#a').textContent === 'foo');
assert(container.querySelector('#b').textContent === 'bar');
assert(container.querySelector('#c').textContent === 'baz');
lookup = { a: 'fizzle', b: 'bop', c: 'fuzz' };
render(container, getTemplate({ items, lookup }));
assert(container.querySelector('#target').childElementCount === 3);
assert(container.querySelector('#a').textContent === 'fizzle');
assert(container.querySelector('#b').textContent === 'bop');
assert(container.querySelector('#c').textContent === 'fuzz');
container.remove();
});

it('map: template changes', () => {
const getTemplate = ({ items }) => {
return html`
Expand Down
12 changes: 5 additions & 7 deletions x-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -1583,13 +1583,11 @@ class Template {

static #map(type, value, lastValue, { node, startNode }, { identify, callback }, name) {
if (type === 'content') {
if (value !== lastValue) {
if (Array.isArray(value)) {
const internals = Template.#setIfMissing(Template.#internals, startNode, () => ({}));
Template.#mapInner(internals, node, startNode, identify, callback, value, name);
} else {
throw new Error(`Unexpected ${name} value "${value}".`);
}
if (Array.isArray(value)) {
const internals = Template.#setIfMissing(Template.#internals, startNode, () => ({}));
Template.#mapInner(internals, node, startNode, identify, callback, value, name);
} else {
throw new Error(`Unexpected ${name} value "${value}".`);
}
} else {
throw new Error(`The ${name} update must be used on ${Template.#getTypeText('content')}, not on ${Template.#getTypeText(type)}.`);
Expand Down

0 comments on commit ce67bc9

Please sign in to comment.