# Refs

# Overview

Refs allow a host widget to access the public functions and fields of a hosted widget.

# Single Widget

To reference a single occurrence of a widget, we create a field to contain the instance of the hosted widget's class, and annotate it with the @EzRef annotation.

@EzRef fields must be nullable.

@EzRef fields start out with null in them.

They are populated automatically by ezFlap shortly after the widgets they are assigned to (with the z-ref attribute) are instantiated.

For example:

# Hosted

RefsSingleHosted

# Host

RefsSingleHost

In the above example, RefsSingleHost hosts RefsSingleHosted.

The z-ref attribute is used to map the hosted widget to the @EzRef field where its instance is to be stored.

The mapping is done using the Assigned Name, which is the value passed as parameter to the @EzRef attribute.

In the above example, RefsSingleHost calls the didUserApprove() public method of the hosted RefsSingleHosted widget when the user presses the "Submit!" button.

USE THE WIDGET CLASS

Like all Flutter stateful widgets, ezFlap widgets consist of two classes.

For example: RefsSingleHost and RefsSingleHostState.

The type of the @EzRef field must be the State class of the hosted widget.

# Multiple Widgets

Sometimes a host widget hosts multiple instances of the same widget.

Such instances can be referenced by multiple, individual @EzRef fields, but with more than just a few instances - it becomes cumbersome. Further, this technique can't be used when the hosted widget instances are created with a z-for loop.

In such cases, we use a Map field and annotate it with the @EzRefs annotation.

By default, the type of the Map's key is String, but it can be overridden with the keyType parameter of the @EzRefs annotation.

In the following example, we use the RefsMultiHosted widget, which is identical to the RefsSingleHosted from the previous section (but has a different name):

# Hosted

RefsMultiHosted

And here is a host widget that uses @EzRefs:

# Host

RefsMultiHost

The refs map is extended, shrunk, and updated by ezFlap automatically, as the set of rendered referenced hosted widgets changes.

We use the z-refs attribute with the refs' Assigned Name to tell ezFlap which @EzRefs field to use.

We use the z-refs-key attribute with the key under which the specific instance of the hosted widget should be stored in the refs Map.

IMPORT GETX

When using @EzRefs, ezFlap uses RxMap internally, so package:get/get.dart needs to be imported.

# Conventions

Strongly-recommended conventions that may become mandatory in a future version:

  • The ref's and refs' Assigned Name (the name provided as parameter to the @EzRef and @EzRefs annotations) should be in camelCase.
  • The ref's name should begin with _$ref_, followed by the Assigned Name.
  • The refs' name should begin with _$refs_, followed by the Assigned Name.

Optional suggested conventions:

  • Place the @EzRef and @EzRefs annotations at the same line as the declaration.
  • Add a // --> this._ref_<Assigned Name> comment at the end of every ref field declaration.
  • Add a // --> this._refs_<Assigned Name> comment at the end of every refs field declaration.
  • Use Live Templates to generate ref and refs declarations quickly and consistently, and without having to remember the syntax.

# Usage

# In Code

When used in code, a ref or refs is accessed using the Derived Name of its declaration.

# In ZML

Hosted widgets can be accessed through their refs from ZML.

For example: RefsSingleHostAccessRefFromZml

# Reactivity

@EzRef and @EzRefs fields are reactive.

When their values change (i.e. as hosted widget instances are added or removed with z-if, z-for, or other methods) - anything that depends on them is also re-evaluated.

Additionally, when accessing hosted widgets via refs, if internally the hosted widget accesses reactive data - then this data becomes a dependency of the accessing code.

The above example demonstrates this.

The host widget calls refsSingleHosted!.didUserApprove() in a z-if in its ZML.

At first, didUserApprove() returns false.

Once the user presses the "Approve!" button (in the hosted widget) - the isApproved bound field of the hosted widget is set to true.

Since bound fields are reactive - the isApproved bound field of the hosted widget becomes a dependent of the z-if of the host widget.

As a result, when the user presses the "Approve!" button - the z-if in the host widget is re-evaluated automatically, calls refsSingleHosted!.didUserApprove(), gets back true, and renders the "Submit!" button.