Skip to content

Commit

Permalink
Merge pull request #1080 from glimmerjs/bugfix/iterable-update-item-d…
Browse files Browse the repository at this point in the history
…estructors
  • Loading branch information
rwjblue authored Apr 29, 2020
2 parents d99294d + 09f0190 commit bec3f43
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
37 changes: 36 additions & 1 deletion packages/@glimmer/integration-tests/test/updating-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1863,7 +1863,7 @@ class UpdatingTest extends RenderTest {
}

@test
'The each helper items destroy correctly (new and updated items)'() {
'{{each}} items destroy correctly when destroying the whole list (new and updated items)'() {
let destroyCount = 0;

this.registerComponent(
Expand Down Expand Up @@ -1897,6 +1897,41 @@ class UpdatingTest extends RenderTest {
assert.equal(destroyCount, 2, 'both list items were correctly destroyed');
}

@test
'{{each}} items destroy correctly if they were added after initial render'() {
let destroyCount = 0;

this.registerComponent(
'Glimmer',
'DestroyableComponent',
'{{@item}}',
class extends EmberishGlimmerComponent {
destroy() {
destroyCount++;
}
}
);

this.render(
stripTight`
{{#each this.list as |item|}}
<div><DestroyableComponent @item={{item}}/></div>
{{/each}}
`,
{
list: ['initial'],
}
);

this.assertHTML(`<div>initial</div>`);

this.rerender({ list: ['initial', 'update'] });
this.assertHTML(`<div>initial</div><div>update</div>`);

this.rerender({ list: ['initial'] });
assert.equal(destroyCount, 1, 'new list item was correctly destroyed');
}

// TODO: port https://github.com/emberjs/ember.js/pull/14082
}

Expand Down
4 changes: 2 additions & 2 deletions packages/@glimmer/runtime/lib/compiled/opcodes/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ APPEND_OPCODES.add(Op.Iterate, (vm, { op1: breaks }) => {
let item = check(stack.peek(), CheckInstanceof(ReferenceIterator)).next();

if (item) {
let tryOpcode = vm.iterate(item.memo, item.value);
vm.enterItem(item.key, tryOpcode);
let tryOpcode = vm.enterItem(item.memo, item.value);
vm.registerItem(item.key, tryOpcode);
} else {
vm.goto(breaks);
}
Expand Down
14 changes: 8 additions & 6 deletions packages/@glimmer/runtime/lib/vm/append.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ export interface InternalVM<C extends JitOrAotBlock = JitOrAotBlock> {

enterList(offset: number): void;
exitList(): void;
iterate(memo: PathReference<unknown>, item: PathReference<unknown>): TryOpcode;
enterItem(key: unknown, opcode: TryOpcode): void;
enterItem(memo: PathReference<unknown>, item: PathReference<unknown>): TryOpcode;
registerItem(key: unknown, opcode: TryOpcode): void;

pushRootScope(size: number): PartialScope<C>;
pushChildScope(): void;
Expand Down Expand Up @@ -363,7 +363,7 @@ export default abstract class VM<C extends JitOrAotBlock> implements PublicVM, I
this.didEnter(tryOpcode);
}

iterate(
enterItem(
memo: VersionedPathReference<unknown>,
value: VersionedPathReference<unknown>
): TryOpcode {
Expand All @@ -378,12 +378,14 @@ export default abstract class VM<C extends JitOrAotBlock> implements PublicVM, I
// this.ip = end + 4;
// this.frames.push(ip);

return new TryOpcode(state, this.runtime, block, new LinkedList<UpdatingOpcode>());
let opcode = new TryOpcode(state, this.runtime, block, new LinkedList<UpdatingOpcode>());
this.didEnter(opcode);

return opcode;
}

enterItem(key: string, opcode: TryOpcode) {
registerItem(key: string, opcode: TryOpcode) {
this.listBlock().map.set(key, opcode);
this.didEnter(opcode);
}

enterList(offset: number) {
Expand Down
6 changes: 2 additions & 4 deletions packages/@glimmer/runtime/lib/vm/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,9 @@ class ListRevalidationDelegate implements IteratorSynchronizerDelegate<Environme
let tryOpcode: Option<TryOpcode> = null;

let result = vm.execute(vm => {
tryOpcode = vm.iterate(memo, item);
vm.pushUpdating();
tryOpcode = vm.enterItem(memo, item);
map.set(key, tryOpcode);
vm.pushUpdating(new LinkedList<UpdatingOpcode>());
vm.updateWith(tryOpcode);
vm.pushUpdating(tryOpcode.children);
});

updating.insertBefore(tryOpcode!, reference);
Expand Down

0 comments on commit bec3f43

Please sign in to comment.