为什么 flutter getx 包导航显示缺少控制器?
why flutter getx package navigation show missing controller?
我有两个页面,设置页面和登录页面,它们与它们的控制器绑定,如 getx 文档所述,我使用 GetMatrial() 小部件来包装应用程序树,但是当我使用 Get.to( ) 进入设置页面转到登录页面,它显示此错误,尽管我进行了文件绑定并在绑定文件中正确添加了用户控制器。
AS Side note : the state management works correctly with no issue ,
the only issue with navigation
> ======== Exception caught by widgets library ======================================================= The following message was thrown building LoginPage(dirty): "UserController" not
> found. You need to call "Get.put(UserController())" or
> "Get.lazyPut(()=>UserController())"
>
> The relevant error-causing widget was: LoginPage
> file:///D:/projects/talab/lib/modules/settings/views/settings_page.dart:141:42
> When the exception was thrown, this was the stack:
> #0 GetInstance.find (package:get/get_instance/src/get_instance.dart:332:7)
> #1 GetView.controller (package:get/get_state_manager/src/simple/get_view.dart:38:37)
> #2 LoginPage.build (package:talab/modules/users/views/login_page.dart:33:26)
> #3 StatelessElement.build (package:flutter/src/widgets/framework.dart:4569:28)
> #4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
the settings controller
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart' as lng;
import 'package:talab/helpers/constant_helper.dart';
import 'package:talab/modules/settings/controllers/settings_controller.dart';
import 'package:talab/modules/users/views/login_page.dart';
class SettingsPage extends GetView<SettingsController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
Image(image: AssetImage("assets/images/logo.png"),height: 100,width: 200,),
SizedBox(height: 10,),
FormBuilder(
// context,
key: controller.settingKey,
// autovalidate: true,
child: Column(
children: <Widget>[
_buildNavigationButton("logout",Icons.logout),
],
)
),
],
),
);
}
Row _buildNavigationButton(text,btnIcon) {
return Row(
children: [
Padding(
padding:EdgeInsets.all(8.0),
child: Icon(btnIcon, color: AppColors.buttonBackgroundColor),
),
Padding(
padding:EdgeInsets.all(15.0),
child:GestureDetector(
onTap: ()=> Get.to(() => LoginPage()),
child: Text(text,style: AppStyles.primaryMediumTextStyle)
),
)
],
);
}
}
the binding helper class
import 'package:talab/modules/home/controllers/home_controller.dart';
import 'package:talab/modules/settings/controllers/settings_controller.dart';
import 'package:talab/modules/todo/controllers/todo_form_controller.dart';
import 'package:talab/modules/todo/controllers/todo_list_controller.dart';
import 'package:talab/modules/users/controllers/user_controller.dart';
import 'package:talab/modules/home/views/home_page.dart';
import 'package:get/get.dart';
import 'package:talab/modules/settings/views/settings_page.dart';
import 'package:talab/modules/todo/views/add_todo_page.dart';
import 'package:talab/modules/todo/views/edit_todo_page.dart';
import 'package:talab/modules/todo/views/todo_list_page.dart';
import 'package:talab/modules/users/views/login_page.dart';
import 'package:talab/modules/users/views/register_page.dart';
import 'constant_helper.dart';
class AppPages {
static const INITIAL = AppRoutes.RootURL;
static final routes = [
//Simple GetPage
GetPage(
name: AppRoutes.HomePageURL,
page: () => HomePage(),
binding: BindingsBuilder(() {
Get.lazyPut<HomeController>(() => HomeController());
// Get.put<Service>(()=> Api());
}),
transition: Transition.fade,
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.LoginPageURL,
page: () => LoginPage(),
binding: BindingsBuilder(() => Get.put(UserController())),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.RegisterPageURL,
page: () => RegisterPage(),
binding: BindingsBuilder(()=>Get.put(UserController())),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.SettingPageURL,
page: () => SettingsPage(),
binding: BindingsBuilder(() {
Get.lazyPut<SettingsController>(() => SettingsController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.TodoListPageURL,
page: () => TodoListPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoListController>(() => TodoListController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.EditTodoPageUrl,
page: () => EditTodoPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoFormController>(() => TodoFormController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.AddTodoPageURL,
page: () => AddTodoPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoFormController>(() => TodoFormController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
];
}
my app widget
class MyApp extends StatelessWidget {
const MyApp();
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialBinding: BindingsBuilder(() {
Get.lazyPut<SettingsController>(() => SettingsController());
// Get.put<Service>(()=> Api());
}),
home: SettingsPage(), //RegisterPage(),
enableLog: true,
debugShowCheckedModeBanner: false,
title: Config.AppName,
theme: AppThemes.appTheme,
locale: LocalizationService.locale,
fallbackLocale: LocalizationService.fallbackLocale,
translations: LocalizationService(),
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
);
}
/*LoginPage(),*/
}
您正在将控制器绑定到命名路由,但使用的是未命名路由。
所以不要使用 onTap: ()=> Get.to(() => LoginPage()),
使用:onTap: ()=> Get.toNamed(AppRoutes.LoginPageURL),
更新
如果你想使用未命名的路由,那么你需要 extend/implement 绑定 class 如:
class LoginBinding extends Bindings{
void dependencies(){
Get.lazyPut(()=> LoginController());
}
}
然后你可以像这样使用它:
Get.to(()=> LoginPage(), binding: LoginBinding());
您也可以像这样在视图文件中定义控制器。
final profileController = Get.put(StudioProfileController());
我有两个页面,设置页面和登录页面,它们与它们的控制器绑定,如 getx 文档所述,我使用 GetMatrial() 小部件来包装应用程序树,但是当我使用 Get.to( ) 进入设置页面转到登录页面,它显示此错误,尽管我进行了文件绑定并在绑定文件中正确添加了用户控制器。
AS Side note : the state management works correctly with no issue , the only issue with navigation
> ======== Exception caught by widgets library ======================================================= The following message was thrown building LoginPage(dirty): "UserController" not
> found. You need to call "Get.put(UserController())" or
> "Get.lazyPut(()=>UserController())"
>
> The relevant error-causing widget was: LoginPage
> file:///D:/projects/talab/lib/modules/settings/views/settings_page.dart:141:42
> When the exception was thrown, this was the stack:
> #0 GetInstance.find (package:get/get_instance/src/get_instance.dart:332:7)
> #1 GetView.controller (package:get/get_state_manager/src/simple/get_view.dart:38:37)
> #2 LoginPage.build (package:talab/modules/users/views/login_page.dart:33:26)
> #3 StatelessElement.build (package:flutter/src/widgets/framework.dart:4569:28)
> #4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
the settings controller
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart' as lng;
import 'package:talab/helpers/constant_helper.dart';
import 'package:talab/modules/settings/controllers/settings_controller.dart';
import 'package:talab/modules/users/views/login_page.dart';
class SettingsPage extends GetView<SettingsController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
Image(image: AssetImage("assets/images/logo.png"),height: 100,width: 200,),
SizedBox(height: 10,),
FormBuilder(
// context,
key: controller.settingKey,
// autovalidate: true,
child: Column(
children: <Widget>[
_buildNavigationButton("logout",Icons.logout),
],
)
),
],
),
);
}
Row _buildNavigationButton(text,btnIcon) {
return Row(
children: [
Padding(
padding:EdgeInsets.all(8.0),
child: Icon(btnIcon, color: AppColors.buttonBackgroundColor),
),
Padding(
padding:EdgeInsets.all(15.0),
child:GestureDetector(
onTap: ()=> Get.to(() => LoginPage()),
child: Text(text,style: AppStyles.primaryMediumTextStyle)
),
)
],
);
}
}
the binding helper class
import 'package:talab/modules/home/controllers/home_controller.dart';
import 'package:talab/modules/settings/controllers/settings_controller.dart';
import 'package:talab/modules/todo/controllers/todo_form_controller.dart';
import 'package:talab/modules/todo/controllers/todo_list_controller.dart';
import 'package:talab/modules/users/controllers/user_controller.dart';
import 'package:talab/modules/home/views/home_page.dart';
import 'package:get/get.dart';
import 'package:talab/modules/settings/views/settings_page.dart';
import 'package:talab/modules/todo/views/add_todo_page.dart';
import 'package:talab/modules/todo/views/edit_todo_page.dart';
import 'package:talab/modules/todo/views/todo_list_page.dart';
import 'package:talab/modules/users/views/login_page.dart';
import 'package:talab/modules/users/views/register_page.dart';
import 'constant_helper.dart';
class AppPages {
static const INITIAL = AppRoutes.RootURL;
static final routes = [
//Simple GetPage
GetPage(
name: AppRoutes.HomePageURL,
page: () => HomePage(),
binding: BindingsBuilder(() {
Get.lazyPut<HomeController>(() => HomeController());
// Get.put<Service>(()=> Api());
}),
transition: Transition.fade,
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.LoginPageURL,
page: () => LoginPage(),
binding: BindingsBuilder(() => Get.put(UserController())),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.RegisterPageURL,
page: () => RegisterPage(),
binding: BindingsBuilder(()=>Get.put(UserController())),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.SettingPageURL,
page: () => SettingsPage(),
binding: BindingsBuilder(() {
Get.lazyPut<SettingsController>(() => SettingsController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.TodoListPageURL,
page: () => TodoListPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoListController>(() => TodoListController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.EditTodoPageUrl,
page: () => EditTodoPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoFormController>(() => TodoFormController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
GetPage(
name: AppRoutes.AddTodoPageURL,
page: () => AddTodoPage(),
binding: BindingsBuilder(() {
Get.lazyPut<TodoFormController>(() => TodoFormController());
// Get.put<Service>(()=> Api());
}),
parameter: {},
middlewares: [],
children: [],
),
];
}
my app widget
class MyApp extends StatelessWidget {
const MyApp();
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialBinding: BindingsBuilder(() {
Get.lazyPut<SettingsController>(() => SettingsController());
// Get.put<Service>(()=> Api());
}),
home: SettingsPage(), //RegisterPage(),
enableLog: true,
debugShowCheckedModeBanner: false,
title: Config.AppName,
theme: AppThemes.appTheme,
locale: LocalizationService.locale,
fallbackLocale: LocalizationService.fallbackLocale,
translations: LocalizationService(),
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
);
}
/*LoginPage(),*/
}
您正在将控制器绑定到命名路由,但使用的是未命名路由。
所以不要使用 onTap: ()=> Get.to(() => LoginPage()),
使用:onTap: ()=> Get.toNamed(AppRoutes.LoginPageURL),
更新
如果你想使用未命名的路由,那么你需要 extend/implement 绑定 class 如:
class LoginBinding extends Bindings{
void dependencies(){
Get.lazyPut(()=> LoginController());
}
}
然后你可以像这样使用它:
Get.to(()=> LoginPage(), binding: LoginBinding());
您也可以像这样在视图文件中定义控制器。
final profileController = Get.put(StudioProfileController());