Bug introduced in V10.4 or earlier and persisting through V11.3
CASE:3875733, confirmed
It seems that Dynamic content is somehow cached by PaneSelector/FrontEnd.
Even weirder, it does respond to evaluation though it uses old values, incorrectly.
Here is a minimal example:
(*our panel, Dynamic + := may seem strange but remember this is only an example*)
paneContent[] := Dynamic[Print[1]; DateString[]]
(*our app implementation with PaneSelector*)
DynamicModule[{pane},
Panel @ Column[{
Button["test", pane = "pane"],
Button["init", pane = "init"],
PaneSelector[{
"default" -> "default",
"pane" -> Dynamic[pane; Print["pane"]; paneContent[]]
}
, Dynamic[ pane ], ImageSize -> {200, 50}
]
}]
]
(*same functionality implemented with Dynamic only*)
DynamicModule[{pane = "init"},
Panel@Column[{
Button["test", pane = paneContent[]],
Button["init", pane = "init"],
Pane[Dynamic[Print["pane"]; pane], {200, 50}]
}]
]
Now toggle between test and init and observe what happens.
The second panel updates date while the first show only the initial one. Even though the Print[] statement is evaluated! I don't understand this at all, it seems that FrontEnd caches paneContent[] somehow.
Can I prevent that?
Answer
Edit
Using knowledge from Dynamic triggered but renders the same content we can enhance our Dynamic to always re-render:
...
"pane" -> Dynamic @ DynamicModule[{$flag = RandomReal[]}
, pane; Print["pane"]; paneContent[]
]
...
This way Dynamic will always see different $flag and re-render.
Old answer
The bug (not documented optimization which is a pain for those who are not aware of it) is confirmed so before it is fixed we need to use something which will mimic PaneSelector instead. So simply Dynamic + Switch.
paneContent[] := Dynamic[ DateString[]]
DynamicModule[
{pane = "init"}
, Panel @ Column[{
Button["test", pane = "pane"]
, Button["init", pane = "init"]
, Dynamic[
Switch[pane, "init", "init", "pane", paneContent[]]
, TrackedSymbols :> {pane}
]
}]
]
This slightly differs from the example in a question as paneContent isn't evaluated each time you click "text" button but only when pane's value changes. This way it is closer to what PaneSelector does.
Comments
Post a Comment