Consider the following example:
DynamicModule[{foo = {Red, Green}, switchColor},
Attributes[switchColor] = {HoldAll};
switchColor[c_] := If[c === Red, c = Green, c = Red];
{
Dynamic[Print["redrawing first"]; foo[[1]]],
Dynamic[Print["redrawing Second"]; foo[[2]]],
Button["Switch first", switchColor[foo[[1]]]],
Button["Switch second", switchColor[foo[[2]]]]
}
]
(in the gif for some reason it appears that the first color is updated incorrectly, while this is not the case)
This works totally fine, but a quick look to the messages reveals that even when changing only a single element of the list, both of the Dynamic
are updated.
Now, this is not really surprising: there is just one variable to be tracked. However, I was wondering if there was a way to go around this, as it can be handy to be able to track independently single elements of a list.
One way around it is to fine foo
as a list of held variables, and wire Dynamic
to those variables directly.
This works, as can be seen in the following:
DynamicModule[{
foo = Table[Hold@Evaluate@Unique["color$"], {2}],
switchColor
},
Scan[# /. Hold[s_] :> Set[s, Red] &, foo];
switchColor[c_Hold] := If[
ReleaseHold@c === Red,
c /. Hold[s_] :> Set[s, Green],
c /. Hold[s_] :> Set[s, Red]
];
{
Dynamic[Print["redrawing first"];
ReleaseHold@foo[[1]]
],
Dynamic[Print["redrawing second"];
ReleaseHold@foo[[2]]
],
Button["Switch first", switchColor[foo[[1]]]],
Button["Switch second", switchColor[foo[[2]]]]
}
]
My problem with this approach is that I suspect that this makes the variables that are actually being used, that is, color$xxxx
, not being defined in front end, as would be the case for variables localised inside a DynamicModule
.
Is there a way around this? Or can I somehow force the variables to be defined in the front end like they would be in a DynamicModule
?
Bonus question:
Why does the above code work?
Having Dynamic
the HoldFirst
attribute I would have expected it not to be able to understand that the variable to be tracked is the one inside the hold in the first element of foo
. How does it do that?
List @@ foo
to recover the whole thing. $\endgroup$