Flow control
In your views you often want to only conditionally show something, or loop through a list of items. For this flutter-view has some intentionally simple flow control keywords.
This will only render the widget if the passed condition is true.
Pug
generated Dart
user-profile(flutter-view :user[User])
.user
.name ${user.name}
.company(if='user.company != null') Works at ${user.company}
UserProfile({required User user}) {
return Container(
child: Column(
children: [
Container(
child: Text('${user.name}'),
),
user.company != null ?
Container(
child: Text('Works at ${user.company}'),
)
: SizedBox(),
],
),
);
}
// left out some flatten operations for simplicity
In the above example, the company will only be shown if the passed user has the company property set.
This will only render the widget if the passed condition is false, otherwise it returns null.
With type and null-safety in Dart, you sometimes need to either pass an argument or null. The normal
if
above will return a SizedBox()
if the condition fails. For building widget trees, this is usually makes sense. However sometimes we need to pass an argument that can be null, depending on a condition. In these edge cases, use if-null.
Pug
generated Dart
app-bar
.title(as='title' null-if='user.name == null') ${user.name}
PlatformAppBar(
title: !(name == null) ?
Container(
child: Text(
'${name}',
),
) : null,
)
In the above example, the title of the
AppBar
widget will be set to null if the user.name
is null
.A slot is a placeholder for a value. It will take the value of the first valid child. Alternatively, you can also directly pass a value into it:
Pug
Generated Dart
wrapper(flutter-view :content[Widget])
slot(:value='content').content
.footer A footer
Column Wrapper({ required Widget content }) {
return Column(
children: __flatten([
content,
//-- FOOTER ----------------------------------------------------------
Container(
child: Text(
'A footer',
),
)
]),
);
}
Slot can function as an if/else. In the next example you see either the .status being shown, or the .empty.
Pug
generated Dart
tasks-page(flutter-view :tasks[List])
scaffold
slot(as='body')
.status(if='tasks.isNotEmpty') You have ${tasks.length} tasks
.empty You have no tasks yet...
Scaffold TasksPage({ required List tasks }) {
return Scaffold(
body: (tasks.isNotEmpty) ?
//-- STATUS ----------------------------------------------------------
Container(
child: Text(
'You have ${tasks.length} tasks',
),
):
true ?
//-- EMPTY ----------------------------------------------------------
Container(
child: Text(
'You have no tasks yet...',
),
)
: Container(),
);
}
As you can see in the above example, you can use the as property to assign the slot value to a parameter as well. In this case, the content of the slot is placed in the body parameter of the Scaffold.
By adding multiple children with if to a slot, you can also create a switch/case:
Pug
slot
.apple(if='fruit=="Apple"')
.pear(if='fruit=="Pear"')
.peach(if='fruit=="Peach"')
.unknown // the fallback
Use for to repeat a widget for every value in a list. For every repetition, the value gets assigned to a variable, which you can use to render the widget and its children.
Pug
generated Dart
tasks-page(flutter-view :tasks[List])
scaffold
slot(as='body')
.task(for='task in tasks')
.title ${task.title}
.description ${task.description}
Scaffold TasksPage({ required List tasks }) {
return Scaffold(
body:
//-- BODY ----------------------------------------------------------
Container(
child: (tasks as List).map((task) {
return
//-- TASK ----------------------------------------------------------
Container(
child: Column(
children: [
//-- TITLE ----------------------------------------------------------
Container(
child: Text(
'${task.title}',
),
),
//-- DESCRIPTION ----------------------------------------------------------
Container(
child: Text(
'${task.description}',
),
)
]),
),
);
}).toList(),
),
);
}
You can also get the index (starting at 0) of the current entry as such:
.task(for='task, index in tasks')
Last modified 1yr ago