aurelia / templating-binding

An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.
MIT License
32 stars 26 forks source link

Repeated template removed inconsistently with if/else bound to a let variable #133

Closed krisdages closed 5 years ago

krisdages commented 5 years ago

I'm submitting a bug report

Please tell us about your environment:

Current behavior: Simplified case:

<template repeat.for="item of items">
   <let letter-matches.bind="item.letter === letter"></let>
   <div if.bind="letterMatches">${item.text}</div>
   <div else style="text-decoration: line-through;">${item.text}</div>
</template>

There is a bug when items is set to a different array (in this case, a filtered one). Some of the items that are not present in the filtered array are not removed from the DOM.

This happens only with both let and if/else.

Expected/desired behavior: The DOM items should match the model items, as with the following cases.

<template repeat.for="item of items">
   <div if.bind="item.letter === letter">${item.text}</div>
   <div else style="text-decoration: line-through;">${item.text}</div>
</template>
<template repeat.for="item of items">
   <let letter-matches.bind="item.letter === letter"></let>
   <div>
      <div if.bind="letterMatches">${item.text}</div>
      <div else style="text-decoration: line-through;">${item.text}</div>
   </div>
</template>

https://codesandbox.io/s/738l45xyq6

(For some reason, the let bindings are not working in the sandbox even though the versions appear to be the latest, and the bundle on gistrun is not updated to the latest versions either. But it's easy to reproduce in a skeleton with let bindings supported).

bigopon commented 5 years ago

I'm quite confused what codesandbox does to the bundle that makes <let/> not working. I tried to reproduce it using normal bundle here https://codesandbox.io/s/2p444yxrwj and it's working fine.

Can you have a check?

krisdages commented 5 years ago

Interesting. Let is working as expected with that bundle (and I don't see the bug that I see in my project with the dependencies installed individually). I'll have to compare and see what's different.

krisdages commented 5 years ago

So I figured out the source of the problem. I have an HTML minifier on my source files that removes the line breaks between the elements. The bug appears when there are no newlines/indentation in the template.

https://codesandbox.io/s/qv6p79wjxq

Click "Toggle Items", and "Item 3 A" on the left side will not be removed. Toggle a few times, and "Item 3 A" will begin being repeated mutliple times.

Had to turn off "prettify on save" in code sandbox btw :P But thanks for giving me a starting point with the scripts fully functional!

And I suppose this issue might be posted under the wrong repo, sorry :)

bigopon commented 5 years ago

@krisdages Thanks for the details. This is an issue with repeat unable to stabilize the range where it starts and ends, when used on template and nested template controller, not really an issue with <let/>. As long as there is a space introduced anywhere between template and its first repeat, it works fine.

bigopon commented 5 years ago

I should say generally it's an issue with nested template controllers with containerless / containerless-like behaviors

krisdages commented 5 years ago

Ah, that's great. Even with the minifier taking out the whitespace, adding a comment before made it start working. Not sure if that is what you meant by "there is a introduced", was there something there you typed that github pulled out?

Working:

 <template repeat.for="item of items">
          <!---->
          <let letter-matches.bind="item.letter === letter"></let>
bigopon commented 5 years ago

I meant as long as there is a space introduced .... I edited that. And that's a nice work around.

EisenbergEffect commented 5 years ago

Closing since we've got a solution here.