CxJS

Sandbox

import { Sandbox } from 'cx/widgets'; Copied

Sandbox acts as a data multiplexer. It selects a value from a storage object based on a dynamic key and exposes it through a recordAlias. When the key changes, Sandbox automatically switches to the corresponding data in storage.

Example

<div>
  <div class="flex gap-4">
    <Radio value={m.place} option="winner" default>
      1st Place
    </Radio>
    <Radio value={m.place} option="second">
      2nd Place
    </Radio>
    <Radio value={m.place} option="third">
      3rd Place
    </Radio>
  </div>
  <Sandbox key={m.place} storage={m.results} recordAlias={m.$contestant}>
    <LabelsTopLayout>
      <TextField value={m.$contestant.firstName} label="First Name" />
      <TextField value={m.$contestant.lastName} label="Last Name" />
    </LabelsTopLayout>
  </Sandbox>
  <div class="mt-4 flex flex-col gap-2">
    <div class="font-medium leading-none">Results</div>
    <div
      class="text-sm"
      text={tpl(
        m.results.winner.firstName,
        m.results.winner.lastName,
        "1. {0} {1}",
      )}
    />
    <div
      class="text-sm"
      text={tpl(
        m.results.second.firstName,
        m.results.second.lastName,
        "2. {0} {1}",
      )}
    />
    <div
      class="text-sm"
      text={tpl(
        m.results.third.firstName,
        m.results.third.lastName,
        "3. {0} {1}",
      )}
    />
  </div>
</div>
Results
1.
2.
3.

Typed Model

Add $contestant (or your chosen alias) to your model interface:

interface PageModel {
  place: string;
  results: Record<string, Contestant>;
  $contestant: Contestant;
}

const m = createModel<PageModel>();

Then use recordAlias={m.$contestant} to bind the record accessor:

<Sandbox key={m.place} storage={m.results} recordAlias={m.$contestant}>
  <TextField value={m.$contestant.firstName} label="First Name" />
</Sandbox>

Sandboxed Routes

Sandbox is commonly used in single-page applications to isolate data belonging to different pages identified by URL parameters. See Routing for more info.

<Route route="~/user/:userId" url={m.url}>
  <Sandbox key={m.$route.userId} storage={m.users} recordAlias={m.$page}>
    <UserProfile />
  </Sandbox>
</Route>

Configuration

PropertyTypeDescription
storagePropStorage binding. All data will be stored inside.
key/accessKeyPropKey value used to access the data from the storage.
recordAliasstringAlias used to expose local data. Defaults to $page.
immutablebooleanIndicate that the data in the parent store should not be mutated.
sealedbooleanIndicate that the data in the store should not be mutated by child stores.