在 Nylo 中创建页面时,页面将扩展 NyState 类。该类提供了有用的实用工具,使开发更容易。
如何使用NyState?
您可以通过扩展来开始使用此类。
class _HomePageState extends NyState<HomePage> {
@override
init() async {
super.init();
}
一旦您的页面扩展了 NyState,您就可以使用 init 方法初始化 widget。该方法在 initState 内部的 Flutter 状态中调用,可以更方便地调用异步函数。
要在 Nylo 中创建新页面,可以运行以下命令。
dart run nylo_framework:main make:page product_page
或者
metro make:page product_page
状态管理
class _SettingsTabState extends NyState<SettingsTab> {
_SettingsTabState() {
stateName = SettingsTab.state;
}
@override
init() async {
super.init();
}
@override
void stateUpdated(data) {
// e.g. to update this state from another class
// updateState(SettingsTab.state, data: "example payload");
}
@override
Widget build(BuildContext context) {
return Container(
child: Cart(),
);
}
}
配置
- Color
返回当前主题的颜色。
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Text("The page loaded", style: TextStyle(
color: color().primaryContent
)
)
);
}
- boot(启动)
boot 方法与 afterLoad 方法结合使用,使异步调用更容易。您可以在 boot 内对 Future 方法调用 await,在等待期间,afterLoad 方法将显示一个加载器(来自您的 config/design.dart 文件)。启动方法完成后,将显示您选择的子组件。
class _HomePageState extends NyState<HomePage> {
@override
boot() async {
await Future.delayed(Duration(seconds: 4));
print('After 4 seconds...');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: afterLoad(child: () {
return Text("The page loaded");
})
)
);
}
- Reboot(重启)
此方法将在您的状态下重新运行启动方法。如果要刷新页面上的数据,这个方法很有用。
class _HomePageState extends NyState<HomePage> {
List<User> users = [];
@override
boot() async {
users = await api<ApiService>((request) => request.fetchUsers());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Users"),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
reboot(); // refresh the data
},
)
],
),
body: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return Text(users[index].firstName);
}
),
);
}
}
- Pop
从路由堆栈中删除当前页面。
class _HomePageState extends NyState<HomePage> {
popView() {
pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: popView,
child: Text("Pop current view")
)
);
}
- showToast
显示 Toast 通知。
class _HomePageState extends NyState<HomePage> {
displayToast() {
showToast(
title: "Hello",
description: "World",
icon: Icons.account_circle,
duration: Duration(seconds: 2),
style: ToastNotificationStyleType.INFO // SUCCESS, INFO, DANGER, WARNING
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: displayToast,
child: Text("Display a toast")
)
);
}
- validate
validate
帮助程序对数据执行验证检查。
class _HomePageState extends NyState<HomePage> {
TextEditingController _textFieldControllerEmail = TextEditingController();
handleForm() {
String textEmail = _textFieldControllerEmail.text;
validate(rules: {
"email address": "email"
}, data: {
"email address": textEmail
}, onSuccess: () {
print('passed validation')
});
}
- changeLanguage
您可以调用以 changeLanguage
更改设备上使用的 json /lang 文件。
class _HomePageState extends NyState<HomePage> {
changeLanguageES() {
await changeLanguage('es');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: changeLanguageES,
child: Text("Change Language".tr())
)
);
}
- whenEnv
当应用程序处于特定状态时,您可以使用 whenEnv 运行函数。例如,如果 .env 文件中的 APP_ENV 变量设置为 "开发中",则 APP_ENV=developing。
class _HomePageState extends NyState<HomePage> {
TextEditingController _textEditingController = TextEditingController();
@override
init() async {
super.init();
whenEnv('developing', perform: () {
_textEditingController.text = 'test-email@gmail.com';
});
}
- lockRelease
该方法将在函数调用后锁定状态,只有在该方法结束后才允许用户提出后续请求。该方法也会更新状态,请使用 isLocked 进行检查。
要展示 lockRelease,最好的例子是设想当用户点击 "登录 "时,我们有一个登录屏幕。我们希望执行异步调用来登录用户,但我们不希望该方法被多次调用,因为这可能会产生不受欢迎的体验。
class _LoginPageState extends NyState<LoginPage> {
_login() async {
await lockRelease('login_to_app', perform: () async {
await Future.delayed(Duration(seconds: 4), () {
print('Pretend to login...');
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isLocked('login_to_app'))
AppLoader(),
Center(
child: InkWell(
onTap: _login,
child: Text("Login"),
),
)
],
)
);
}
一旦您点击 _login 方法,它就会阻止任何后续请求,直到原始请求结束。isLocked('login_to_app') 辅助函数用于检查按钮是否锁定。在上面的示例中,您可以看到我们使用它来确定何时显示加载小工具。
- isLocked
该方法将使用 lockRelease 辅助函数检查状态是否已锁定。
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isLocked('login_to_app'))
AppLoader(),
],
)
);
}
- isLoading
该方法将检查状态是否正在加载。
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
if (isLoading()) {
return AppLoader();
}
return Scaffold(
body: Text("The page loaded", style: TextStyle(
color: colors().primaryContent
)
)
);
}
- afterLoad
该方法可用于显示加载程序,直到状态完成“加载”。
您还可以使用afterLoad(child: () {}, loadingKey: 'home_data')
参数检查其他加载键。
class _HomePageState extends NyState<HomePage> {
@override
init() async {
super.init();
awaitData(perform: () async {
await Future.delayed(Duration(seconds: 4));
print('4 seconds after...');
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: afterLoad(child: () {
return Text("Loaded");
})
);
}
- afterNotLocked
该方法将检查状态是否已锁定。
如果状态为锁定,则将显示加载组件。
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: afterNotLocked('login', child: () {
return MaterialButton(
onPressed: () {
login();
},
child: Text("Login"),
);
}),
)
);
}
login() async {
await lockRelease('login', perform: () async {
await Future.delayed(Duration(seconds: 4));
print('4 seconds after...');
});
}
}
- afterNotNull
我们可以使用 afterNotNull 来显示加载中的 widget,直到变量被设置。
试想一下,如果您需要使用 Future 调用从数据库中获取用户账户,这可能需要 1-2 秒的时间,那么您可以对该值使用 afterNotNull 直到获取到数据。
class _HomePageState extends NyState<HomePage> {
User? _user;
@override
init() async {
super.init();
_user = await api<ApiService>((request) => request.fetchUser()); // example
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: afterNotNull(_user, child: () {
return Text(_user!.firstName);
})
);
}
- setLoading
您可以使用 setLoading 更改为 "加载 "状态。
第一个参数接受一个 bool 值,表示是否正在加载,下一个参数允许你为加载状态设置一个名称,例如 setLoading(true,name:'refreshing_content');
。
class _HomePageState extends NyState<HomePage> {
@override
init() async {
super.init();
setLoading(true, name: 'refreshing_content');
await Future.delayed(Duration(seconds: 4));
setLoading(false, name: 'refreshing_content');
}
@override
Widget build(BuildContext context) {
if (isLoading(name: 'refreshing_content')) {
return AppLoader();
}
return Scaffold(
body: Text("The page loaded")
);
}