ExotikArch – Flutter setState 性能增强⚡
ExotikArch for Flutter。使用Flutter快速交付生产应用。
- 全局状态管理
- 导航服务
- 辅助小部件,例如加载器和处理器。
- 无缝异常处理,无需重复代码
- 支持Isolates以卸载API调用。
*注意
目前,ExotikArch以这个应用项目的形式存在。如果这个项目能获得足够的关注,我将把它打包并发布到pubdev上。
运行它
flutter run
模块
状态管理
ExotikArch使用内置的setState函数来处理全局状态管理。它设计用于与MVC模式良好配合。我们创建控制器来处理业务逻辑。要构建一个简单的控制器,只需将其扩展为ExoController
import 'package:exotik_todos_app/exotik_arch/exotik_arch.dart';
class TodosController extends ExoController<TodosRetainer> {
void Function(void Function() fn)? setState;
TodosRetainer? retainer;
TodosController(
this.setState,
{
TodosRetainer?initRetainer
}
) : super(
setState,
initRetainer: initRetainer ?? TodosRetainer()
);
void dispose() async {
super.dispose();
}
}
ExoController接受一个泛型类型,该类型将作为控制器数据的模型。例如,在TodosController的情况下,这个TodosRetainers引用定义为,
class TodosRetainer {
late List<Todo> todosList;
TodosRetainer(){
todosList = [];
}
}
按照约定,将retainer引用保存在与控制器相同的文件中。要从UI调用控制器,请使用此语法,
late TodosController todosController;
@override
void initState() {
todosController = TodosController(
this.setState,
initRetainer: anaGlobalRetainers.todosRetainer
);
super.initState();
}
请注意,将一个initRetainer传递给了TodosContoller构造函数。这就是全局状态支持的方式。所有全局retainer都放在一个AnaGlobalRetinaters引用中,并在需要时传递给控制器。如果传递了initRetainer,则控制器将使用现有状态进行初始化,从而产生全局状态效果。
导航服务
随时随地导航。只需使用,
import 'package:exotik_todos_app/exotik_arch/exotik_arch.dart';
ExoNavService.push(
MainPage()
);
辅助小部件
ExotikArch附带2个主要辅助小部件。它们基于一个非常简单的想法构建。几乎90%的应用只做两件事。它们加载并显示数据。或者它们将数据提交给服务器并等待响应。ExotikArch分别将它们视为数据加载和过程处理。要加载数据,有一个名为ExoDataLoader的辅助小部件。它接受ExoControler的引用。并且每当控制器处于加载状态时,它都会自动渲染一个加载指示器,并在数据渲染完成后停止。
我们将逻辑暴露在控制器中,UI会自动更新。
Future<void> getTodos({
bool reload = true
}) async {
try {
if(!reload){
if(retainer!.todosList.isNotEmpty){
return;
}
}
List<Todo> _todosList;
exoDataLoaderHelper.startLoading(); // Start Data Loader
_todosList = await apiInterface.getTodos();
exoDataLoaderHelper.stopLoading(); // Stop Data Loader
if(_todosList != null){
retainer!.todosList = _todosList;
}
} on ExoException catch (e, s){
exoDataLoaderHelper.showError(e); // Handle Error Messages
return null;
}
return;
}
进程也是如此。有一个ExoProcessHandler,它将显示一个叠加的加载指示器,并在进程完成后停止它。
Future<bool> login(
String email,
String password,
{
bool rememberMe: true
}
) async {
try{
AppUser? _appUser;
exoProcessHandlerHelper.startLoading(); // Start Process Loader
_appUser = await apiInterface.logIn(
email,
password,
);
exoProcessHandlerHelper.stopLoading(); // Stop Process Loader
appUser = _appUser;
if(appUser != null){
if(rememberMe){
appUser?.cache();
}
return true;
} else {
return false;
}
} on ExoException catch (e, s){
exoProcessHandlerHelper.showError(e); // Handle Error Messages
return false;
}
}
而ExoDataLoader、ExoProcessHandler的调用方式与常规小部件一样,
@override
Widget build(BuildContext context) {
return ExoProcessHandler(
exoProcessHandlerHelper: todosController.exoProcessHandlerHelper,
child: Container(),
);
}
@override
Widget build(BuildContext context) {
return ExoProcessHandler(
exoProcessHandlerHelper: authController.exoProcessHandlerHelper,
child: Container()
);
}
异常处理
ExotikArch有一个内置机制来在内部处理所有异常。这通过控制器和小部件工作。所有异常都被解析到一个单一类ExoException中,该类有一个friendlyErrorMessage字段。当ExoProcessHandler或ExoDataLoader小部件出现问题时,此消息会自动显示。闪信会构造并提示给用户。
工作卸载 – 支持Isolates
Isolates支持目前非常基础。我们为此使用内置的compute()函数。它将生成Isolates,在其中发出网络请求,然后将其注销。实现可以在api_interface.dart文件中找到。
ComputeRequest computeRequest = ComputeRequest(
requestURL,
RequestType.POST,
body: body,
);
CDioResponse<Map<String, dynamic>> response = await compute<ComputeRequest, CDioResponse<Map<String, dynamic>>>(
cRequest,
computeRequest
); // Execute the network request With Isolate
CDioResponse<Map<String, dynamic>> response = await cRequest(
computeRequest
); // Execute the Network Request WithOut Isolate
贡献
欢迎 Pull requests。对于重大更改,请先打开一个 issue 来讨论您想进行的更改。