Flutter数据模型管理插件modddels的使用
Flutter数据模型管理插件modddels的使用
简介
modddels
是一个强大的代码生成器,允许您创建自验证的数据模型,这些模型具有编译安全的状态、无缝的失败处理和易于单元测试的特点。它解决了在应用中创建和验证数据模型时遇到的一些常见问题,如在哪里进行验证、如何区分有效和无效实例等。
动机
假设您想要建模一个 Student
对象,该对象有姓名、年龄和电子邮件地址。传统上,您可能会像下面这样定义您的类:
class Student {
Student({
required this.name,
required this.age,
required this.email,
});
final String name;
final int age;
final String email;
}
然而,这种方法存在一些问题:
- 在哪里验证
name
,age
, 和email
? - 如何区分有效的
Student
实例和无效的实例? - 如何确保将有效的
Student
实例传递给需要它们的函数或小部件?
这些问题都可以通过使用 modddels
包来解决。
特性
- 自我验证:模型在创建时即被验证。
- 密封类:您的模型是一个密封类,具有不同的状态(有效、无效等)。
- 失败处理:当模型无效时,它会持有导致失败的原因,您可以随时访问。
- 值相等性和不可变性:所有模型都是不可变的,并且重写了
operator ==
和hashCode
。 - 单元测试:轻松测试您的模型及其验证逻辑。
示例
以下是一个使用 modddels
的简单示例。完整的例子可以在 GitHub 上找到。
完整示例 Demo
import 'package:example/modddels/age.dart';
import 'package:example/modddels/user.dart';
import 'package:example/modddels/username.dart';
// In this example, [Username], [Age] and [User] are all "modddels".
void main() {
final username =
Username('dash_the_bird', availabilityService: MyAvailabilityService());
final age = Age(20);
final user = User.appUser(username: username, age: age);
// Map over the different validation states of the user.
user.map(
valid: (valid) => greetUser(valid),
invalidMid: (invalidMid) => redirectToProfileInfoScreen(invalidMid),
);
}
// This method can only accept a [ValidUser], i.e a valid instance of [User].
void greetUser(ValidUser user) {
final username = user.username.value;
// Map over the different types of users ([AppUser] or [Moderator])
final greeting = user.mapUser(
appUser: (validAppUser) => 'Hey $username ! Enjoy our app.',
moderator: (validModerator) =>
'Hello $username ! Thanks for being a great moderator.');
print(greeting);
}
// This method can only accept an [InvalidUserMid], i.e an invalid instance of
// [User] specifically because of a failure in the validationStep named "mid".
void redirectToProfileInfoScreen(InvalidUserMid user) {
print('Redirecting to profile ...');
// Checking if the `age` is invalid, and handling the only possible failure.
user.age.mapOrNull(
invalidValue: (invalidAgeValue) => invalidAgeValue.legalFailure.map(
minor: (_) => print('You should be 18 to use our app.'),
),
);
// Checking if the `username` is invalid, and handling its possible failures.
user.username.map(
valid: (validUsername) {},
invalidValue1: (invalidUsernameValue1) {
// Handling failures of the "length" validation.
if (invalidUsernameValue1.hasLengthFailure) {
final errorMessage = invalidUsernameValue1.lengthFailure!.map(
empty: (value) => 'Username can\'t be empty.',
tooShort: (value) =>
'Username must be at least ${value.minLength} characters long.',
tooLong: (value) =>
'Username must be less than ${value.maxLength} characters long.',
);
print(errorMessage);
}
// Handling failures of the "characters" validation.
if (invalidUsernameValue1.hasCharactersFailure) {
final errorMessage = invalidUsernameValue1.charactersFailure!.map(
hasWhiteSpace: (hasWhiteSpace) =>
'Username can\'t contain any whitespace character.',
hasSpecialCharacters: (hasSpecialCharacters) =>
'Username can only contain letters, numbers and dashes.',
);
print(errorMessage);
}
},
invalidValue2: (invalidUsernameValue2) {
// Handling failures of the "availability" validation. This validation is
// part of a separate validationStep than the two previous ones for
// optimization purposes.
final errorMessage = invalidUsernameValue2.availabilityFailure.map(
unavailable: (unavailable) => 'Username is already taken.',
);
print(errorMessage);
},
);
}
更多关于Flutter数据模型管理插件modddels的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据模型管理插件modddels的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,管理数据模型通常涉及创建和管理应用状态,而modddels
(假设你指的是类似mobx
、provider
或riverpod
等状态管理插件的误写)这样的插件可以帮助你更有效地实现这一点。虽然没有一个确切名为modddels
的Flutter插件,但我会展示如何使用provider
插件来管理数据模型,因为provider
是Flutter社区中非常流行的一个状态管理解决方案。
使用provider
插件管理数据模型
首先,确保在你的pubspec.yaml
文件中添加了provider
依赖:
dependencies:
flutter:
sdk: flutter
provider: ^6.0.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
创建一个数据模型
假设我们有一个简单的用户数据模型:
// models/user.dart
class User {
final String name;
final int age;
User(this.name, this.age);
}
创建一个ChangeNotifier
来管理这个模型
我们将使用ChangeNotifier
来包装我们的用户数据,这样我们就可以监听它的变化:
// providers/user_provider.dart
import 'package:flutter/material.dart';
import 'models/user.dart';
class UserProvider with ChangeNotifier {
User _user = User('John Doe', 30);
User getUser() {
return _user;
}
void setUser(User newUser) {
_user = newUser;
notifyListeners();
}
}
在应用中提供UserProvider
在你的应用入口(通常是main.dart
)中,使用MultiProvider
来提供UserProvider
:
// main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user_provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserProvider()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Provider Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: UserScreen(),
);
}
}
在UI中消费UserProvider
最后,在你的UI组件中,使用Consumer
或Provider.of<T>(context)
来访问UserProvider
:
// screens/user_screen.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/user.dart';
import 'providers/user_provider.dart';
class UserScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('User Info'),
),
body: Center(
child: Consumer<UserProvider>(
builder: (context, userProvider, child) {
User user = userProvider.getUser();
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Name: ${user.name}'),
Text('Age: ${user.age}'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
userProvider.setUser(User('Jane Doe', 25));
},
child: Text('Update User'),
),
],
);
},
),
),
);
}
}
以上代码展示了如何使用provider
插件来管理一个简单的用户数据模型。你可以根据需要扩展这个模型,添加更多的属性和方法,以及更多的状态管理逻辑。