diff --git a/packages/htmlbars-compiler/tests/dirtying-test.js b/packages/htmlbars-compiler/tests/dirtying-test.js index c369bc46..877ee672 100644 --- a/packages/htmlbars-compiler/tests/dirtying-test.js +++ b/packages/htmlbars-compiler/tests/dirtying-test.js @@ -36,9 +36,9 @@ function commonSetup() { } }); - registerHelper('each', function(params) { + registerHelper('each', function(params, hash, blocks) { var list = params[0]; - + if(list.length !== 0) { for (var i=0, l=list.length; i 0) { @@ -47,6 +47,9 @@ function commonSetup() { this.yieldItem(item.key, undefined, item); } } + } else if (blocks.inverse.yield) { + blocks.inverse.yield(); + } }); } @@ -490,6 +493,27 @@ test("MorphLists in childNodes are properly cleared", function() { strictEqual(destroyedRenderNodeCount, 6, "cleanup hook was invoked again"); }); +test("MorphLists in each else are properly cleared", function() { + var template = compile(`{{#each items as |item|}}
{{item.name}}
{{else}}
{{noItems}}
{{/each}}`); + + let a1 = { key: "a", name: "A1" }; + let a2 = { key: "a", name: "A2" }; + var object = {items: [], noItems: "items not found"}; + + var result = template.render(object , env); + equalTokens(result.fragment, `
items not found
`); + + object.items.push(a1); + object.items.push(a2); + result.rerender(env, object); + + equalTokens(result.fragment, "
A1
A2
"); + strictEqual(destroyedRenderNodeCount, 1, "cleanup hook was invoked for else morph"); + + result.rerender(env, { items: [] }); + strictEqual(destroyedRenderNodeCount, 5, "cleanup hook was invoked for each morph"); +}); + test("Pruned render nodes invoke a cleanup hook when cleared", function() { var object = { condition: true, value: 'hello world' }; var template = compile('
{{#if condition}}

{{value}}

{{/if}}
'); diff --git a/packages/htmlbars-runtime/lib/hooks.js b/packages/htmlbars-runtime/lib/hooks.js index fc3f7c6a..57561c34 100644 --- a/packages/htmlbars-runtime/lib/hooks.js +++ b/packages/htmlbars-runtime/lib/hooks.js @@ -4,6 +4,7 @@ import { createChildMorph } from "./render"; import { keyLength, shallowCopy } from "../htmlbars-util/object-utils"; import { validateChildMorphs } from "../htmlbars-util/morph-utils"; import { RenderState, clearMorph, clearMorphList, renderAndCleanup } from "../htmlbars-util/template-utils"; +import { visitChildren } from "../htmlbars-util/morph-utils"; import { linkParams } from "../htmlbars-util/morph-utils"; /** @@ -258,6 +259,11 @@ function yieldItem(template, env, parentScope, morph, renderState, visitor) { handledMorphs[foundMorph.key] = foundMorph; yieldTemplate(template, env, parentScope, foundMorph, renderState, visitor)(blockArguments, self); } else { + if(morph.childNodes){ + visitChildren(morph.childNodes, function (node) { + clearMorph(node, env, true); + }); + } var childMorph = createChildMorph(env.dom, morph); childMorph.key = key; morphMap[key] = handledMorphs[key] = childMorph;