11

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?

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • paneContent[]:=Dynamic[pane;Print[Stack[_]];DateString[]] with "pane" -> paneContent[] seems working. So it looks like the Dynamic in paneContent[] needs to be triggered explicitly. But I don't understand what is the relation between the global pane and the localized pane. – Silvia Mar 22 '17 at 20:12
  • @Silvia paneContent is independent from DynamicModule so can't use it. The more that bare Dynamic works, I just won't use PaneSelector. For me it is just crazy that this prints Print["pane"]; paneContent[] but it doesn't evaluate paneContent[]. I suppose it is a side effect of something which should have made our lifes easier, again. Thanks for your attention :)\ – Kuba Mar 22 '17 at 20:23

1 Answers1

6

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.

Kuba
  • 136,707
  • 13
  • 279
  • 740