The BeagleView is the most important structure of Beagle Flutter. This is the object responsible for holding the representation of the view, processing the JSON and notifying every listener when anything changes. Every BeagleView has an object called “renderer”, which is used to make changes to the current UI tree.
The Beagle Navigator is responsible for creating BeagleViews. Each page of the navigator is associated with a BeagleWidget and each BeagleWidget is instantiated by the StackNavigator with a BeagleView.
The BeagleView is composed of the following methods:
From all the methods above, three are interesting for the developer using the Beagle Library: getRenderer
, getNavigator
and getTree
. They can be used to alter the UI tree from within a component or make a navigation to another Beagle page.
Examples of default components (package beagle_components) that use the BeagleView are:
To gain access of the BeagleView responsible for the current UI tree, you can make use of the 3rd parameter of the method buildForBeagle
of the ComponentBuilder.
See below the ComponentBuilder of the default component “LazyComponent”:
class _LazyBuilder extends ComponentBuilder {
@override
Widget buildForBeagle(element, children, view) {
final initialState = element.getAttributeValue('initialState');
return BeagleLazyComponent(
path: element.getAttributeValue('path'),
initialState: initialState == null ? null : BeagleUIElement(initialState),
beagleId: element.getId(),
view: view,
child: children.isEmpty ? Container() : children[0],
);
}
}
If you can’t receive the BeagleView from the ComponentBuilder, you can also access it using the BuildContext, as long as the context descends from a BeagleWidget. To do this, you can call the utility method findAncestorBeagleView(context)
.
Every action handler receives the BeagleView that triggered it via the named parameter view
. See below an example of an action that adds a text (parameter “text”) to a given component node (parameter “target”, id of the node).
import 'package:beagle/beagle.dart';
final Map<String, ActionHandler> actions = {
'custom:addText': ({required action, required element, required view, required context}) {
final textNode = {'_beagleComponent_': 'beagle:text', text: action.getAttributeValue('text')};
view.getRenderer().doFullRenderer(textNode, TreeUpdateMode.append, action.getAttributeValue('target'))
},
// ...
}
The BeagleView can be accessed from the BuildContext as long as the context descends from a BeagleWidget. The function that finds the BeagleView given a BuildContext is findAncestorBeagleView(context)
.
The most useful part of a BeagleView is its renderer. A renderer is an object containing the following functions:
Alters the UI tree by adding or replacing a branch of the current tree. It accepts the following positional parameters:
BeagleUIElement
). This is required.String
) of the node where the new branch should be placed. If not informed, the root node is used.TreeUpdateMode
). The available modes are:replaceComponent
: this is the default value, used in case no mode is provided. The replaceComponent
mode replaces the node identified by the anchor (2nd parameter) with the tree provided in the 1st parameter.replace
: replaces the entire set of children of the node identified by the anchor (2nd parameter).append
: adds the new node at the end of the list of children of the node identified by the anchor (2nd parameter).prepend
: adds the new node at the start of the list of children of the node identified by the anchor (2nd parameter).i.e. if only the first parameter is provided, it renders an entire new tree.
Check below how the LazyComponent
uses this method:
Future<void> _fetchLazyView() async {
try {
final component = await beagle.viewClient.fetch(RemoteView(widget.path));
widget.view.getRenderer().doFullRender(component, widget.beagleId, TreeUpdateMode.replace);
} catch (err) {
beagle.logger.error('BeagleLazyComponent: error: $err');
}
}
In the code above, beagle
is the current BeagleService. To see how to obtain a reference to the current BeagleService, check this article. widget.view
is the BeagleView passed by the ComponentBuilder of the LazyComponent. widget.beagleId
has also been provided by the ComponentBuilder and is the id of the node in Beagle UI tree.
To check the full implementation, visit our github repository and look for the widget BeagleLazyComponent
.
Does the same as doFullRender
, but in less steps. It is a faster method that assumes the node already exists in the tree and only some properties have been modified. This is useful for actions like setContext
, where it just needs to update some values, without altering the structure of the tree.
If you don’t know which method to call, prefer using doFullRender
. The parameters of the two methods are exactly the same.
This is the most complex rendering method and it’s rarely needed. It’s used for creating components like the ListView and GridView. Imagine you need to render multiple nodes at once using a template, and this template uses expressions that must be evaluated with the value of the current iteration. Doing this with the other two methods would be very inefficient, so this method receives a template, a set of values and creates the nodes accordingly, with a single render event.
The doTemplateRender
accepts the following named parameters:
TemplateManager templateManager
: set of templates to use. It’s more than one because different types of elements in the data set can have different templates. Required.String anchor
: the id of the node where the new branch should be placed. Required.List<List<BeagleDataContext>> contexts
: matrix of contexts where each line represents an item to be rendered according to the templateManager. Required.BeagleUIElement Function(BeagleUIElement, int)? componentManager
: optional. When set, the component goes through this function before being finally rendered. It’s a chance for altering properties like the id.TreeUpdateMode? mode
: optional. The mode for inserting the new nodes. The default value is replace
. Check all available options in the previous section.To see an example of how this method can be used, please, check the implementation of the widget DynamicList
in the package beagle_components
.
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.