I'm Using GetX As A State Management Tool and it was very helpful,
but I got a bug when navigating to a page and going back the page controller doesn't get disposed and the onClose()
method doesn't get called so I can't dispose the controller manually using Get.delete<Controller>()
.
and I checked answers here pointing out to initialize the controller in the build()
method and it also didn't work.
I'm using GetX ^4.6.5
Navigating with Named Navigation i.e Get.toNamed('/page1 )
UPDATE
code snippet the Page
class UnitsList extends StatelessWidget {
const UnitsList({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
const horizontalPadding = EdgeInsets.symmetric(horizontal: 10);
final UnitsListController controller = Get.put(UnitsListController());
return Scaffold(
appBar: AppBar(
title: Text('Units List'),
centerTitle: true,
),
body: Padding(
padding: horizontalPadding,
child:GetX<UnitsListController>(
builder: (_)=>controller.isBusy.value
?const AppCircularIndicator()
: SingleChildScrollView(
child: Column(
children: [
GetBuilder<UnitsListController>(
builder:(_)=> ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.unitsList.length,
itemBuilder: (context, index) {
var item = controller.unitsList[index];
return GestureDetector(
onTap: () {
controller.selectedUnit = item;
print('${controller.selectedUnit!.rent}');
controller.onUnitTap();
},
child: AppUnitCard(
//...
),
);
},
),
),
],
)
),
)
),
);
}
}
And the Controller
class UnitsListController extends GetxController {
final _className = 'Units List Controller';
List<Unit> unitsList = [];
String? _requestType;
RxBool isBusy = false.obs;
Unit? selectedUnit;
@override
void onInit() async {
log('onInit', name: _className);
isBusy.value = true;
//Some APIs Calls and handling data
super.onInit();
}
@override
void onReady() {
isBusy.value = false;
log('onReady', name: _className);
super.onReady();
}
@override
void onClose() {
log('onClose', name: _className);
super.onClose();
}
void onUnitTap() {
log('_requestType : $_requestType', name: _className);
if(selectedUnit == null ||_requestType==null){
return;
}
var selectedUnitData = {NavigationParams.unit: selectedUnit!.toJson()};
if (_requestType == NotificationsStrings.evacuation) {
Get.toNamed(AppRoutes.evacuationRequestPage,
arguments: selectedUnitData);
} else if (_requestType == NotificationsStrings.maintenance) {
Get.toNamed(AppRoutes.maintenanceRequestPage,
arguments: selectedUnitData);
} else if (_requestType == NotificationsStrings.renting) {
Get.toNamed(AppRoutes.paymentServicesList, arguments: selectedUnitData);
} else if (_requestType == NavigationParams.searchUnitTapRequest) {
Get.toNamed(AppRoutes.unitDetailsPage,
arguments: selectedUnitData,
parameters: {
NavigationParams.unitDetailsKey: NavigationParams.unitDetailsRent
});
}
else if (_requestType == NavigationParams.customerViewUnitTapRequest) {
Get.toNamed(AppRoutes.unitDetailsPage,
arguments: selectedUnitData,
);
}
else if (_requestType == NavigationParams.ownerInvitingSpUnitTapRequest) {
Get.toNamed(AppRoutes.servicesProvidersList,
arguments: selectedUnitData);
}
else if (_requestType == NavigationParams.ownerViewUnitTapRequest ||
_requestType == NavigationParams.ownerViewEmptyUnitTapRequest ||
_requestType == NavigationParams.ownerViewOccupiedUnitTapRequest) {
Get.toNamed(AppRoutes.unitDetailsPage,
arguments: selectedUnitData,
parameters: {
NavigationParams.unitDetailsKey: NavigationParams.unitDetailsEdit
});
}
}
}
so please any help would be appreciated
So I've solved my problem with a work around approach, so don't judge me if that's not a best practice or a poor solution.
lets consider that i have a two pages Page1(),Page2()
and their controllers
Page1Controller(),Page2Controller()
.
and i wanted to go back and forth and when i revisit Page2() i wanted it's controller to be re-Initialized.
so what i did simply is when i'm at Page1()
and before i call Get.to(Page2())
i make sure that the Page2Controller()
is already deleted so i use Get.delete<Page2Controller>();
and to test this you can see the loge Page2Controller() onInit()
.
so the full solution code is like that:
Page1Controller Navigation:
Get.delete<Page2Controller>();
Get.to(Page2());
and Page2Controller :
import 'dart:developer';
class Page2Controller extends GetxController {
final _className='Page 2 Controller';
@override
void onInit() async{
log('onInit',name:_className);
}
}
you will find out that with this approach the Page2Controller will get Re-Initialized every time you go to Page2