S. *_*GIR 16 dependency-injection dart flutter flutter-getx
我有两个页面:HomePage和DetailsPage以及关联的GetxControllers。
主页:
class HomePage extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('HomePage')),
body: Container(
child: Obx(
() => ListView.builder(
itemCount: controller.task.length,
itemBuilder: (context, index) {
return ListTile(
leading: Text('${index + 1}'),
title: Text(controller.task[index]["name"]),
onTap: () {
Get.to(
DetailsPage(),
arguments: controller.task[index]["name"],
);
},
);
},
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
家庭控制器:
class HomeController extends GetxController {
final TaskRepository repository;
HomeController({@required this.repository}) : assert(repository != null);
final _task = [].obs;
set task(value) => this._task.assignAll(value);
get task => this._task;
onInit() {
super.onInit();
getAllTask();
}
getAllTask() {
repository.getAll().then((value) => task = value);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,HomeController依赖于TaskRepository,它是一个模拟存储库。
还有我的详细信息页面:
class DetailsPage extends GetView<DetailsController> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
GestureDetector(
onTap: () {
Get.back();
},
child: Row(
children: [
Icon(Icons.arrow_back),
Text('Go Back'),
],
),
),
Expanded(
child: Center(
child: Obx(
() => Text(controller.taskDetail.value),
),
),
),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
详情控制器:
class DetailsController extends GetxController {
final taskDetail = ''.obs;
@override
void onInit() {
super.onInit();
taskDetail.value = Get.arguments;
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个AppDependency类来初始化依赖项(控制器、存储库、API 客户端等):
class AppDependencies {
static Future<void> init() async {
Get.lazyPut(() => HomeController(repository: Get.find()));
Get.lazyPut(() => DetailsController());
Get.lazyPut(() => TaskRepository(apiClient: Get.find()));
Get.lazyPut(() => TaskClient());
}
}
Run Code Online (Sandbox Code Playgroud)
我通过调用来初始化所有依赖AppDependencies.init()项main():
void main() async {
await AppDependencies.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您在第三张图片中看到的那样,从DetailsPage返回到HomePage再返回到DetailsPage会导致出现异常:
"DetailsController" not found. You need to call "Get.put(DetailsController())" or "Get.lazyPut(()=>DetailsController())"
Run Code Online (Sandbox Code Playgroud)
但我已经在main(). 我也尝试过使用Get.put()而不是,Get.lazyPut()但我发现对于Get.put()任何其他依赖项的任何依赖项,都必须在依赖项之前注册。例如,HomeController 依赖于 TaskRepository,因此如果使用Get.put()如下所示,TaskRepository 必须位于 HomeController 之前:
Get.put(TaskRepository());
Get.put(HomeController());
Run Code Online (Sandbox Code Playgroud)
这不是我想要的,因为我不想手动跟踪之前发生的事情。我发现这会导致如果有一个后退按钮(几乎每个页面都有)。
我在这里做错了什么?
如果您不想使用fenix = true,您可以在您的 click 方法中使用类似的内容:
try {
///find the controller and
///crush here if it's not initialized
final authController = Get.find<AuthController>();
if(authController.initialized)
Get.toNamed('/auth');
else {
Get.lazyPut(() => AuthController());
Get.toNamed('/auth');
}
} catch(e) {
Get.lazyPut(() => AuthController());
Get.toNamed('/auth');
}
Run Code Online (Sandbox Code Playgroud)
关于内存,重要的是要考虑fenix参数:
如果使用 [Get.delete()] 删除了实例,[builder()] 的内部寄存器将保留在内存中以重新创建实例。因此,将来对 [Get.find()] 的调用将返回相同的实例。
您需要绑定所有控制器并在GetMaterialApp中添加。
您面临这个问题是因为当您使用 back 时它会删除或删除控制器,例如:[GETX] "LoginController" onDelete() 调用
为了防止出现此问题,您需要创建InitialBinding。
初始绑定
class InitialBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut(() => LoginController(LoginRepo()), fenix: true);
Get.lazyPut(() => HomeController(HomeRepo()), fenix: true);
}
}
Run Code Online (Sandbox Code Playgroud)
在主要方法中:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Get.put(AppController());
return GetMaterialApp(
title: StringConst.APP_NAME,
debugShowCheckedModeBanner: false,
defaultTransition: Transition.rightToLeft,
initialBinding: InitialBinding(),
theme: ThemeData(
primarySwatch: ColorConst.COLOR,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: RoutersConst.initialRoute,
getPages: routes(),
);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢
| 归档时间: |
|
| 查看次数: |
59428 次 |
| 最近记录: |