After redraw marko regenarates key for component.
I have a modal component, that can be shown and hidden.
<div class=['modal large-modal', !state.visible && 'hidden' ]>
<div class="modal-background" onClick("handleMaskClick") />
<div class="exit-button" />
<div class="modal-container">
<div class="modal-body" key="body">
<include (input.renderBody) />
</div>
<div class="modal-footer">
<include (input.actions) />
</div>
</div>
</div>
I am using this component to display a timer component
<large-modal key="popup-window" on-hide('pauseTimer', 'timer')>
<@renderBody>
<timer key="timer" />
</@renderBody>
</large-modal>
This timer component has a method pause, that would pause the timer after modal is closed. To do that, i have added method on hide event on modal, that looks like this.
pauseTimer(timerKey) {
this.getComponent(timerKey).pause();
}
This functionality does not work, as after each manipulation on modal, that is state.visibility changes, the contents are redrawn, including timer key="timer" and marko sets this components id now to timer_1, which makes my functionality with call pauseTimer('timer') to not work, as this component no longer is identified by this key.
I am expecting key to not change in scenario when component is redrawn.
@matisskeiris I created a branch which adds a test for this but I was unable to reproduce the issue.
Would you be able to pull down this branch and help in creating a failing test?
You can run the test added in my branch by running:
node ./test/__runner__/browser/cli.js --page preserve-transcluded-key-on-state-change --automated
@DylanPiercey We actually hit this same problem today in a drop-down component we built where the body of the dropdown is a transcluded component. If the conditional is on the include inside another component, the key gets incremented the second time the component is rendered, but the parent context still tries to lookup the key using the original key name with no index (because the parent is not aware that the component was destroyed and recreated). This seems to happen because when the component is rerendered, it uses the parent's keySequence and the ___lookup still contains the key, despite the child being destroyed. This makes sense since the destruction of the transcluded component happened in a child component so the parent component is not updated and the keySequence is not "rebuilt".
Here's a simple project that shows the issue. https://github.com/jasonmacdonald/marko-conditional-include (I'll see if I can find some time to turn this into a failing, but the demo project was what I used to narrow down the issue in our project).
There appear to be a couple options to resolve this issue:
keySequence.__lookup in the parent context.keySequence to be rebuilt (I believe) without the transcluded component. _this is our workaround for the moment_componentLookup which only has the new key which has been incremented.Fixed in #1086
Most helpful comment
@DylanPiercey We actually hit this same problem today in a drop-down component we built where the body of the dropdown is a transcluded component. If the conditional is on the include inside another component, the key gets incremented the second time the component is rendered, but the parent context still tries to lookup the key using the original key name with no index (because the parent is not aware that the component was destroyed and recreated). This seems to happen because when the component is rerendered, it uses the parent's
keySequenceand the___lookupstill contains the key, despite the child being destroyed. This makes sense since the destruction of the transcluded component happened in a child component so the parent component is not updated and thekeySequenceis not "rebuilt".Here's a simple project that shows the issue. https://github.com/jasonmacdonald/marko-conditional-include (I'll see if I can find some time to turn this into a failing, but the demo project was what I used to narrow down the issue in our project).
There appear to be a couple options to resolve this issue:
keySequence.__lookupin the parent context.keySequenceto be rebuilt (I believe) without the transcluded component. _this is our workaround for the moment_componentLookupwhich only has the new key which has been incremented.