我有两页:GetxControllers. HomePage和DetailsPage
HomePage
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"],
);
},
);
},
),
),
),
);
}
}
HomeController
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);
}
}
如您所见,HomeController依赖于一个TaskRepository,这是一个模拟回购。
和我的DetailsPage
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),
),
),
),
],
),
);
}
}
DetailsController
class DetailsController extends GetxController {
final taskDetail = ''.obs;
@override
void onInit() {
super.onInit();
taskDetail.value = Get.arguments;
}
}
我创建了一个AppDependencies类来初始化依赖项(控制器、存储库、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());
}
}
我正在通过在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(),
);
}
}
正如您在第三张图片中所看到的,从DetailsPage返回到HomePage,然后返回DetailsPage,会导致一个异常,即:
"DetailsController" not found. You need to call "Get.put(DetailsController())" or "Get.lazyPut(()=>DetailsController())"
但我已经在main()
上这么做了。我也尝试使用Get.put()
而不是Get.lazyPut()
,但是我发现对于Get.put()
,任何其他依赖项的依赖都必须在依赖依赖的依赖项之前注册。例如,HomeController依赖于TaskRepository,因此如果使用Get.put()
,则TaskRepository必须位于HomeController之前:
Get.put(TaskRepository());
Get.put(HomeController());
这不是我想要的,因为我不想在手动跟踪之前跟踪什么。我发现,如果有一个后退按钮(几乎每一页都有),就会产生这种情况。
我在这里做错了什么?
发布于 2021-06-09 15:21:19
如果不想使用fenix = true
,可以在单击方法中使用类似的内容:
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');
}
关于内存,重要的是要考虑fenix
参数:
如果使用Get.delete()删除实例,构建器()的内部寄存器将保留在内存中以重新创建实例。因此,将来对Get.find()的调用将返回相同的实例。
发布于 2021-03-30 02:45:23
您需要绑定所有控制器和添加到GetMaterialApp.中的
您面临这一问题,因为当您当时使用它时,它会删除或删除控制器,比如:GETX "LoginController“onDelete(),称为
为了防止这个问题,您需要创建InitialBinding.
InitialBinding
class InitialBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut(() => LoginController(LoginRepo()), fenix: true);
Get.lazyPut(() => HomeController(HomeRepo()), fenix: true);
}
}
的主要方法:
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(),
);
}
}
谢谢
发布于 2021-02-10 15:54:08
带绑定的更新答复:
您可以更好地控制控制器如何和何时使用绑定和智能管理进行初始化。因此,如果每次访问页面时都需要使用onInit来触发,则可以使用绑定来实现。为详细信息页设置专用绑定类。
class DetailsPageBinding extends Bindings {
@override
void dependencies() {
// any controllers you need for this page you can lazy init here without setting fenix to true
}
}
如果您尚未使用GetMaterialApp而不是MaterialApp,则需要这样做。我建议在页面上抛出static const id = 'details_page';
,这样您就不必为路由处理原始字符串了。
GetMaterialApp的一个基本示例如下所示。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: HomePage.id,
title: 'Material App',
getPages: [
GetPage(name: HomePage.id, page: () => HomePage()),
// adding the new bindings class in the binding field below will link those controllers to the page and fire the dependancies override when you route to the page
GetPage(name: DetailsPage.id, page: () => DetailsPage(), binding: DetailsPageBinding()),
],
);
}
}
然后你需要做你的路由
Get.toNamed(DetailsPage.id)
原来的答案:
将fenix: true
添加到懒惰的init中;检查lazyPut上的文档。
Get.lazyPut(() => HomeController(repository: Get.find()), fenix: true);
https://stackoverflow.com/questions/66138542
复制相似问题