Skip to content

<Controller>

Overview

The <Controller> component creates a stateful widget from a registered Controller class that manages business logic and state for the UI it renders. Controllers are Dart classes that handle data loading, state management, and business rules, then expose that data to their child widgets via dependencies. See Controllers.

The <Controller> component:

  • Instantiates a stateful Controller instance
  • Initializes the controller asynchronously
  • Binds controller data to XML via dependencies
  • Handles loading and error states automatically
  • Inflates child widgets with access to controller data

Attributes

Name Type Description Required Default
name String The name of the registered controller class to instantiate Yes -
options Map Optional parameters passed to the controller instance via options property No {}
errorWidget Widget Widget to display if controller initialization fails No ErrorWidget
progressWidget Widget Widget to display during controller initialization No SizedBox.shrink()
keepAlive bool Keeps the controller's state alive in lazy parents such as PageView and TabBarView No false
key Key Widget key for controlling widget identity No null
for String The name of the parent's attribute that will be assigned this component No null
visible bool Controls widget visibility No true

Examples

Minimal

A controller binds values and callbacks; its child fragment reads them:

XML
<Controller name="CounterController">
    <Column>
        <Text data="Count: ${count}"/>
        <TextButton onPressed="${increment}">
            <Text data="Increment"/>
        </TextButton>
    </Column>
</Controller>
Dart
class CounterController extends Controller {
  var count = 0;

  @override
  void bindDependencies() {
    dependencies.setValue("count", count);
    dependencies.setValue("increment", () {
      dependencies.setValue("count", ++count);
    });
  }
}

Loading Data

XML
<Controller for="body" name="LicensesController">
    <ListView.builder itemCount="${length(ossLicenses)}">
        <builder for="itemBuilder" vars="_,index">
            <Card elevation="2" shadowColor="#44000000" >
                <Column crossAxisAlignment="start">
                    <Text data="${ossLicenses[index].name}">
                        <TextStyle for="style" fontWeight="700"/>
                    </Text>
                    <Text data="${ossLicenses[index].license}">
                        <TextStyle for="style" fontWeight="400"/>
                    </Text>
                </Column>
            </Card>
        </builder>
    </ListView.builder>
</Controller>
Dart
class LicensesController extends Controller {
  dynamic ossLicenses;

  @override
  Future<void> init() async {
    String data = await DefaultAssetBundle
        .of(context)
        .loadString("resources/licenses.json");
    ossLicenses = jsonDecode(data);
  }

  @override
  void bindDependencies() {
    dependencies.setValue("ossLicenses", ossLicenses);
  }
}

See Also

  • <DynamicBuilder> - For simpler async data loading without controller
  • <ValueListener> - For reactive state management
  • <EventListener> - For handling events