The behaviour we see is due to the fact that the expression referencing totalPages
has dynamic dependencies, but it is not wrapped in Dynamic
itself. The simple fix is to add Dynamic
in front of StringJoin
:
DynamicModule[{totalpages, pagesize},
Dynamic@StringJoin[{"of ", ToString@totalpages, "."}],
Initialization :> (pagesize = 5;
totalpages = Ceiling[Length[Range[456]]/pagesize];)
]
(* of 92. *)
However, it is much more interesting to examine the aspects of DynamicModule
that explain the peculiar results we see. In particular, the exhibited expressions reveal some of the localization strategies used at different stages of the DynamicModule
evaluation process.
Discussion
For the discussion that follows, we will use an expression that reveals three important stages that occur during DynamicModule
evaluation:
DynamicModule[{x, y = "y-eval"}
, {ToString[x], x, Dynamic[x], ToString[y], y, Dynamic[y]}
, Initialization :> (x = "x-init"; y = "y-init")
]
(* {"x$123", x$$, "x-init", "y-eval", "y-eval", "y-init"} *)
The results "x$123"
, x$$
and "x-init"
correspond to the three stages in question. An outline of the sequence of events is as follows.
Stage 1: Initial Evaluation
As per the documentation of DynamicModule
, the expression is first evaluated after localizing all variables as if by Module
. This generates the symbols x$123
and y$123
. Only latter is assigned a value.
The body of the DynamicModule
is evaluated with these bindings in place. ToString[x]
captures the normally unobservable symbol name x$123
in a string:
(* {"x$123", x$123, Dynamic[x$123], "y-eval", "y-eval", Dynamic[y$123]} *)
Stage 2: Placeholder Localization
The preceding result will be used to build the actual dynamic boxes. Any local variables are renamed again to become so-called "placeholders":
(* { "x$123", $CellContext`x$$, Dynamic[$CellContext`x$$],
"y-eval", "y-eval", Dynamic[$CellContext`y$$] } *)
Placeholders are necessary because a rendered DynamicModule
can be duplicated by copy-and-paste, each copy needing to use different variables. Placeholders are replaced by such unique variables when rendered for display.
Stage 3: Display
When the DynamicModule
becomes visible, the placeholders are resolved, and the initialization form is evaluated. Both x$$
and y$$
receive values, but only Dynamic
parts of the expression will reflect those values. That is why we see the final result which, when rendered, shows the non-dynamic reference to the placeholder x$$
as an unevaluated symbol:
(* {"x$123", x$$, "x-init", "y-eval", "y-eval", "y-init"} *)
The present response has glossed over some details in the interest of brevity. There are more than three stages, and some of the stages operate upon box forms instead of the simple expressions shown above. (75323) discusses some of those details in more depth.
StringJoin
in aDynamic@Refresh[ #, None ]
which has solved it. Thanks. $\endgroup$