Issue
In my Flutter app I use GetxController as a viewModel for every view:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'track_activity_view_model.dart';
// Main widget of the view
class TrackActivityView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<TrackActivityViewModel>(
init: TrackActivityViewModel(),
builder: (viewModel) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text('Registra un\'attività ')),
body: viewModel.serviceEnabled
? AskPermissionWidget()
: TrackingWidget(viewModel),
));
});
}
}
class AskPermissionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<TrackActivityViewModel>(
init: TrackActivityViewModel(),
builder: (viewModel) {
// Some code that use viewModel
return Container();
});
}
}
class TrackingWidget extends StatelessWidget {
final TrackActivityViewModel viewModel;
TrackingWidget(this.viewModel);
@override
Widget build(BuildContext context) {
// Some code that use viewModel
return Container();
}
}
When I write some nested widget, I’m wondering if is it better
- Call the controller ex-novo (AskPermissionWidget)
or
- Pass the controller as a parameter (TrackingWidget)
Are there any differences?
Thank-you very much.
Solution
In GetX you need not to struggle anymore with dependency injection (this is the title of what you asked). Even it is one of the main benefits of GetX over other packages.
You need to do following steps to get the things around:
-
Just create (and bind) your ViewModel(s) (or better named Controllers) using :
a.
Get.put
orGet.lazyPut
methods used in constructor orbuild
method of the top widgetb. or using
init
parameter ofGetBuilder
in the top widget to construct a new controllerc. or using Bindings for any page to define the Controllers related to that page.
-
Find your Controller in the child widgets or anywhere else using
myViewModel = Get.find<MyViewModel>()
. You need not any more to initialize it in the child or pass it within constructors. It always find the right Controller for you. Or if you want it to be used inGetBuilder
you could use theGetBuilder
in the child without anyinit
paramter or anything else. Just write this in your child widget :
return GetBuilder<TrackActivityViewModel>(
builder: (viewModel) {
// Some code that use viewModel
return Container();
});
and the GetBuilder itself finds the right Controller for you. No need to pass it anything else (after you ensured that the controller is initialized in a top widget or it is a permanent
controller which will not be removed from the memory).
Isn’t it simple ?! As I mentioned, this is the major advantage of GetX over the other state management packages.
note : If you want multiple instances of a single Controller
class, you would be able to pass a unique tag
parameter in Get.put
or Get.lazyPut
or in the GetBuilder
or GetX
widget to uniquely define the Controller
and then in the child widgets or anywhere you want to find it use that unique tag
to identify which one do you want.
Summary : GetX always finds the right Controller.
Answered By – Hossein Hadi
Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)